Skip to content
Snippets Groups Projects
Commit e997a9f7 authored by OZGCloud's avatar OZGCloud
Browse files

Merge remote-tracking branch 'origin/OZG-5778_entry-metadata' into OZG-6735_fim_metadata

# Conflicts:
#	fim-adapter/src/main/java/de/ozgcloud/eingang/fim/AntragstellerExtractor.java
#	fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimDataMapper.java
#	fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimSchemeAdapter.java
#	fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimService.java
#	fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimServiceITCase.java
parents ab8fd942 ccb1a87c
Branches
Tags
1 merge request!2Ozg 6735 fim metadata
Showing
with 466 additions and 209 deletions
......@@ -31,7 +31,7 @@
<parent>
<groupId>de.ozgcloud.eingang</groupId>
<artifactId>eingang-manager</artifactId>
<version>2.13.0-SNAPSHOT</version>
<version>2.15.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<artifactId>common</artifactId>
......
package de.ozgcloud.eingang;
import org.aspectj.lang.annotation.Pointcut;
public class EingangAspectPointcuts {
@Pointcut("execution(public * *(..))")
void anyPublicMethods() {
// aspect pointcut - no implementation needed
}
@Pointcut("within(de.ozgcloud..*)")
void anythingInOzgCloud() {
// aspect pointcut - no implementation needed
}
@Pointcut("anyPublicMethods() && anythingInOzgCloud()")
void anyPublicMethodInOzgCloud() {
// aspect pointcut - no implementation needed
}
@Pointcut("anyPublicMethodInOzgCloud() && target(de.ozgcloud.eingang.semantik.enginebased.EngineBasedMapper)")
void publicMethodInEngineBasedMapper() {
// aspect pointcut - no implementation needed
}
}
package de.ozgcloud.eingang;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import de.ozgcloud.common.logging.AspectLoggingUtils;
@Aspect
@Component
public class EingangLoggingAspect extends EingangAspectPointcuts {
@Before("publicMethodInEngineBasedMapper()")
public void onEngineBasedMapper(JoinPoint joinPoint) {
AspectLoggingUtils.log(joinPoint);
}
@AfterReturning(pointcut = "publicMethodInEngineBasedMapper()", returning = "returnValue")
public void afterServiceMethod(JoinPoint joinPoint, Object returnValue) {
AspectLoggingUtils.logReturnValue(joinPoint, returnValue);
}
}
......@@ -48,7 +48,8 @@ public class FormData {
@Builder.Default
private FormHeader header = FormHeader.builder().build();
private ZustaendigeStelle zustaendigeStelle;
@Singular
private List<ZustaendigeStelle> zustaendigeStelles;
@ToString.Exclude
private Antragsteller antragsteller;
@ToString.Exclude
......@@ -63,16 +64,21 @@ public class FormData {
@Singular
private List<IncomingFile> representations;
private FormDataControl control;
@Builder.Default
private FormDataControl control = FormDataControl.builder().build();
@Getter
@Builder
@Builder(toBuilder = true)
@ToString
public static class FormDataControl {
private Optional<Representations> representations;
@Builder.Default
private Optional<Representations> representations = Optional.empty();
@Builder.Default
private Optional<FormMetaData> metaData = Optional.empty();
}
@Getter
@Builder
@Builder(toBuilder = true)
public static class Representations {
private String primaryFormDataRepresentation;
private String primaryFormDataPdfRepresentation;
......
package de.ozgcloud.eingang.common.formdata;
import java.time.ZonedDateTime;
public interface FormMetaData {
ZonedDateTime getOrigin();
ZonedDateTime getDelivery();
/**
* Returns the value of the Entry, or null if this MetaData contains no Entry
* for the name.
*
* @param name Name of the requested Entry
* @return Value of the Entry
*/
String getEntry(String name);
}
package de.ozgcloud.eingang.common.formdata;
import java.util.Optional;
import de.ozgcloud.eingang.common.formdata.FormData.FormDataControl;
import de.ozgcloud.eingang.common.formdata.FormData.Representations;
public class FormDataControlTestFactory {
public static String PRIMARY_FORM_DATA_REPRESENTATION = "Antrag.xml";
public static FormDataControl create() {
return createBuilder().build();
}
public static FormDataControl.FormDataControlBuilder createBuilder() {
return FormDataControl.builder()
.representations(Optional.of(Representations.builder()
.primaryFormDataRepresentation(PRIMARY_FORM_DATA_REPRESENTATION)
.build()))
.metaData(Optional.of(FormMetaDataTestFactory.create()));
}
}
......@@ -51,6 +51,8 @@ public class FormDataTestFactory {
public static final String ATTACHMENT_GROUP_2 = "FileGroup2";
public static final String VORGANG_ID = "vorgangId";
public static FormData create() {
return createBuilder().build();
}
......@@ -60,6 +62,7 @@ public class FormDataTestFactory {
.header(FormHeaderTestFactory.create())
.antragsteller(AntragstellerTestFactory.create())
.zustaendigeStelle(ZustaendigeStelleTestFactory.create())
.control(FormDataControlTestFactory.create())
.formData(Map.of(
SIMPLE_VALUE_KEY, SIMPLE_VALUE,
SUBFORM_KEY, SUBFORM_VALUE,
......
package de.ozgcloud.eingang.common.formdata;
import java.time.ZonedDateTime;
public class FormMetaDataTestFactory {
public static final String XTA_IDENTIFIER_ENTRY_NAME = "xtaIdentifier";
public static final String XTA_IDENTIFIER = "vbe:010550120100";
public static final String OE_ID = "010550120100";
public static FormMetaData create() {
return new FormMetaData() {
@Override
public ZonedDateTime getOrigin() {
return ZonedDateTime.now();
}
@Override
public ZonedDateTime getDelivery() {
return ZonedDateTime.now();
}
@Override
public String getEntry(String name) {
switch (name) {
case XTA_IDENTIFIER_ENTRY_NAME:
return XTA_IDENTIFIER;
}
return null;
}
};
}
}
......@@ -4,7 +4,7 @@
<parent>
<groupId>de.ozgcloud.eingang</groupId>
<artifactId>eingang-manager</artifactId>
<version>2.13.0-SNAPSHOT</version>
<version>2.15.0-SNAPSHOT</version>
</parent>
<artifactId>enterprise-adapter</artifactId>
<name>EM - Enterprise Interface Adapter</name>
......@@ -87,10 +87,9 @@
<executions>
<execution>
<id>build-image</id>
<phase>
install</phase>
<phase>install</phase>
<goals>
<goal>build-image</goal>
<goal>build-image-no-fork</goal>
</goals>
</execution>
</executions>
......
......@@ -64,6 +64,7 @@ class EnterpriseEntryITCase {
assertThat(formData).isNotNull();
}
@Test
void shouldHaveNoOfRepresentations() {
var formData = doPostRequest();
......
......@@ -4,7 +4,7 @@
<parent>
<groupId>de.ozgcloud.eingang</groupId>
<artifactId>eingang-manager</artifactId>
<version>2.13.0-SNAPSHOT</version>
<version>2.15.0-SNAPSHOT</version>
</parent>
<artifactId>fim-adapter</artifactId>
<name>Eingangs Adapter - FIM</name>
......
package de.ozgcloud.eingang.fim;
import de.ozgcloud.eingang.common.formdata.Antragsteller;
import de.ozgcloud.eingang.common.formdata.FormData;
import java.util.Map;
public interface AntragstellerExtractor {
default void extractAntragsteller(final FormData.FormDataBuilder builder, final FormData initialFormData) {
final FormData current = builder.build();
final Map<String, Object> anzeigenErsteller = FimDataUtil.getSubmap(current.getFormData(), "G17002112");
final Map<String, Object> anschrift = FimDataUtil.getSubmap(anzeigenErsteller, "G60000086");
Antragsteller antragsteller = Antragsteller.builder()
.vorname(FimDataUtil.getValue(anzeigenErsteller, "F60000228").orElse(null))
.nachname(FimDataUtil.getValue(anzeigenErsteller, "F60000227").orElse(null))
.email(FimDataUtil.getValue(anzeigenErsteller, "F60000242").orElse(null))
.strasse(FimDataUtil.getValue(anschrift, "F60000243").orElse(null))
.hausnummer(FimDataUtil.getValue(anschrift, "F60000244").orElse(null))
.plz(FimDataUtil.getValue(anschrift, "F60000246").orElse(null))
.ort(FimDataUtil.getValue(anschrift, "F60000247").orElse(null))
.build();
builder.antragsteller(antragsteller);
}
}
package de.ozgcloud.eingang.fim;
import de.ozgcloud.eingang.common.formdata.FormData;
import de.ozgcloud.eingang.common.formdata.FormHeader;
import de.ozgcloud.eingang.common.formdata.IncomingFile;
import de.ozgcloud.eingang.semantik.enginebased.EngineBasedSemantikAdapter;
import lombok.extern.log4j.Log4j2;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.util.Optional;
import de.ozgcloud.eingang.common.formdata.FormData;
import de.ozgcloud.eingang.common.formdata.FormData.FormDataControl;
import de.ozgcloud.eingang.common.formdata.FormData.Representations;
import de.ozgcloud.eingang.common.formdata.IncomingFile;
import de.ozgcloud.eingang.semantik.enginebased.EngineBasedSemantikAdapter;
import lombok.NonNull;
import lombok.extern.log4j.Log4j2;
@Log4j2
@Component
......@@ -22,9 +28,14 @@ public class FimBasedAdapter implements EngineBasedSemantikAdapter {
static final String FIM_FORM_ENGINE_NAME = "FIM";
static final String DEFAULT_FORMDATA_REPRESENTATION_NAME = "Antrag.xml";
@Autowired
private FimService fimService;
@Autowired(required = false)
private List<FimEngineBasedMapper> mappers = Collections.emptyList();
@Override
public boolean isResponsible(final FormData formData) {
final String formEngineName = formData.getHeader().getFormEngineName();
......@@ -33,42 +44,53 @@ public class FimBasedAdapter implements EngineBasedSemantikAdapter {
@Override
public FormData parseFormData(final FormData initialFormData) {
var mapped = useMappers(initialFormData);
LOG.info("FIM Mapper running to map formData");
final Optional<String> entryPointOpt = getEntryPoint(initialFormData.getHeader());
if (entryPointOpt.isEmpty()) {
LOG.error("No entry point found in metadata file for fim data mapping");
return initialFormData;
}
final Optional<IncomingFile> fileOpt = findFile(initialFormData, entryPointOpt.get());
if (fileOpt.isEmpty()) {
return findFile(initialFormData, getEntryPoint(initialFormData.getControl()))
.map(primaryRepresentation -> doParsing(mapped, primaryRepresentation))
.orElseGet(() -> {
LOG.error("Entry point file not found for fim data mapping");
return initialFormData;
return mapped;
});
}
try {
final Document document = loadDocument(fileOpt.get());
return fimService.transformDocument(document, initialFormData);
} catch (ParserConfigurationException | SAXException | IOException | FimException e) {
LOG.error("Can't transform document into fim formdata");
return initialFormData;
private FormData useMappers(FormData inFormData) {
var processedFormData = inFormData;
for (var mapper : mappers) {
processedFormData = mapper.parseFormData(processedFormData);
}
return processedFormData;
}
private Optional<IncomingFile> findFile(final FormData formData, final String name) {
for (IncomingFile file : formData.getRepresentations()) {
if (file.getName().endsWith(name)) {
return Optional.of(file);
return formData.getRepresentations().stream()
.filter(file -> file.getName().endsWith(name))
.findFirst();
}
private FormData doParsing(@NonNull FormData formData, @NonNull IncomingFile formDataPrimaryRepresentation) {
try {
return fimService.transformDocument(loadDocument(formDataPrimaryRepresentation), formData);
} catch (ParserConfigurationException | SAXException | IOException | FimException e) {
LOG.error("Can't transform document into fim formdata.", e);
return formData;
}
return Optional.empty();
}
private Optional<String> getEntryPoint(final FormHeader formHeader) {
// FIXME OZG-5778 sollte über formdata metadaten kommen statt aus dem meta file geparsed zu werden
return Optional.of("Antrag.xml");
String getEntryPoint(FormDataControl formDataControl) {
return formDataControl.getRepresentations().map(Representations::getPrimaryFormDataRepresentation)
.orElseGet(() -> {
LOG.error("No entry point found in metadata file for fim data mapping. Trying default.");
return DEFAULT_FORMDATA_REPRESENTATION_NAME;
});
}
private Document loadDocument(final IncomingFile incomingFile) throws ParserConfigurationException, IOException, SAXException {
final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
return builder.parse(incomingFile.getContentStream());
}
}
package de.ozgcloud.eingang.fim;
import de.ozgcloud.eingang.common.formdata.FormData;
import de.ozgcloud.eingang.common.formdata.IncomingFile;
import de.ozgcloud.eingang.common.formdata.IncomingFileGroup;
import lombok.extern.log4j.Log4j2;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
import org.apache.commons.lang3.function.TriFunction;
import org.springframework.stereotype.Service;
import org.w3c.dom.Document;
......@@ -12,7 +12,8 @@ import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import java.util.*;
import de.ozgcloud.eingang.common.formdata.FormData;
import lombok.extern.log4j.Log4j2;
@Service
@Log4j2
......
package de.ozgcloud.eingang.fim;
import de.ozgcloud.eingang.semantik.enginebased.EngineBasedMapper;
public interface FimEngineBasedMapper extends EngineBasedMapper {
}
package de.ozgcloud.eingang.fim;
import lombok.extern.log4j.Log4j2;
import java.util.Map;
import java.util.Optional;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import java.util.Map;
import java.util.Optional;
import lombok.extern.log4j.Log4j2;
@Log4j2
public abstract class FimSchemeAdapter implements ZustaendigeStelleExtractor, AntragstellerExtractor, VorgangsnameExtractor {
public abstract class FimSchemeAdapter {
public abstract FimSchemeIdentifier forIdentifier();
......
package de.ozgcloud.eingang.fim;
import de.ozgcloud.eingang.common.formdata.FormData;
import de.ozgcloud.eingang.common.formdata.FormHeader;
import io.micrometer.common.util.StringUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import jakarta.annotation.PostConstruct;
import lombok.extern.log4j.Log4j2;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import de.ozgcloud.eingang.common.formdata.Antragsteller;
import de.ozgcloud.eingang.common.formdata.FormData;
import de.ozgcloud.eingang.common.formdata.FormHeader;
import io.micrometer.common.util.StringUtils;
import lombok.extern.log4j.Log4j2;
@Service
@Log4j2
......@@ -43,7 +46,9 @@ public class FimService {
private static final FimSchemeAdapter DEFAULT_FIM_SCHEME_ADAPTER = new FimSchemeAdapter() {
@Override
public FimSchemeIdentifier forIdentifier() { return null; }
public FimSchemeIdentifier forIdentifier() {
return null;
}
};
@PostConstruct
......@@ -86,11 +91,10 @@ public class FimService {
final FimScheme scheme = getSchemeForIdentifier(schemeName);
final FormData.FormDataBuilder builder = fimDataMapper.apply(document, scheme, initialFormData);
final FimSchemeAdapter adapter = scheme.getSchemeAdapter();
builder.header(initialFormData.getHeader());
adapter.extractVorgangsname(builder, initialFormData);
adapter.extractAntragsteller(builder, initialFormData);
adapter.extractZustaendigeStelle(builder, initialFormData);
extractAntragsteller(builder, initialFormData);
extractVorgangsname(builder, initialFormData);
return builder.build();
}
......@@ -104,4 +108,32 @@ public class FimService {
}
return fimScheme;
}
private void extractAntragsteller(final FormData.FormDataBuilder builder, final FormData initialFormData) {
final FormData current = builder.build();
final Map<String, Object> anzeigenErsteller = FimDataUtil.getSubmap(current.getFormData(), "G17002112");
final Map<String, Object> anschrift = FimDataUtil.getSubmap(anzeigenErsteller, "G60000086");
Antragsteller antragsteller = Antragsteller.builder()
.vorname(FimDataUtil.getValue(anzeigenErsteller, "F60000228").orElse(null))
.nachname(FimDataUtil.getValue(anzeigenErsteller, "F60000227").orElse(null))
.email(FimDataUtil.getValue(anzeigenErsteller, "F60000242").orElse(null))
.strasse(FimDataUtil.getValue(anschrift, "F60000243").orElse(null))
.hausnummer(FimDataUtil.getValue(anschrift, "F60000244").orElse(null))
.plz(FimDataUtil.getValue(anschrift, "F60000246").orElse(null))
.ort(FimDataUtil.getValue(anschrift, "F60000247").orElse(null))
.build();
builder.antragsteller(antragsteller);
}
private void extractVorgangsname(final FormData.FormDataBuilder builder, final FormData initialFormData) {
final FormData current = builder.build();
final Optional<String> vorgangsname = FimDataUtil.getValue(current.getFormData(), "G17003529", "G05001479", "G05001480", "F05002753");
final FormHeader.FormHeaderBuilder headerBuilder = current.getHeader().toBuilder();
headerBuilder.formName(vorgangsname.orElse(null));
builder.header(headerBuilder.build());
}
}
\ No newline at end of file
package de.ozgcloud.eingang.fim;
import de.ozgcloud.eingang.common.formdata.FormData;
public interface ZustaendigeStelleExtractor {
default void extractZustaendigeStelle (final FormData.FormDataBuilder builder, final FormData initialFormData) {}
}
package de.ozgcloud.eingang.fim;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import org.springframework.stereotype.Component;
import de.ozgcloud.eingang.common.formdata.FormData;
import de.ozgcloud.eingang.common.formdata.ZustaendigeStelle;
import lombok.NonNull;
@Component
class ZustaendigeStelleMapper implements FimEngineBasedMapper {
static final String XTA_IDENTIFIER_ENTRY_NAME = "xtaIdentifier";
// TODO OZG-7086 umstellen auf FIM Headerdaten
@Override
public FormData parseFormData(FormData formData) {
return formData.getControl().getMetaData()
.map(metaData -> metaData.getEntry(XTA_IDENTIFIER_ENTRY_NAME))
.filter(Objects::nonNull)
.map(oeId -> setOrganisationsEinheitId(formData.getZustaendigeStelles(), oeId))
.map(zustStelle -> formData.toBuilder().zustaendigeStelle(zustStelle).build())
.orElse(formData);
}
private ZustaendigeStelle setOrganisationsEinheitId(List<ZustaendigeStelle> stelles, @NonNull String oeid) {
var builder = stelles.isEmpty() ? ZustaendigeStelle.builder() : stelles.getFirst().toBuilder();
extractOrganisationsEinheitId(oeid).ifPresent(builder::organisationseinheitenId);
return builder.build();
}
Optional<String> extractOrganisationsEinheitId(@NonNull String xtaIdentifier) {
var idx = xtaIdentifier.indexOf(":");
if (idx < 0) {
return Optional.empty();
}
return Optional.of(xtaIdentifier.substring(idx + 1));
}
}
package de.ozgcloud.eingang.fim;
import static org.assertj.core.api.Assertions.*;
import java.util.Optional;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import de.ozgcloud.eingang.common.formdata.FormData.Representations;
import de.ozgcloud.eingang.common.formdata.FormDataControlTestFactory;
class FimBasedAdapterTest {
@InjectMocks
private FimBasedAdapter adapter;
@Nested
class TestGetEntryPoint {
@Test
void shouldReturnPrimaryRepresentation() {
var result = adapter.getEntryPoint(FormDataControlTestFactory.create());
assertThat(result).isEqualTo(FormDataControlTestFactory.PRIMARY_FORM_DATA_REPRESENTATION);
}
@Test
void shouldReturnDefaultOnMissingRepresentations() {
var result = adapter.getEntryPoint(FormDataControlTestFactory.createBuilder().representations(Optional.empty()).build());
assertThat(result).isEqualTo(FimBasedAdapter.DEFAULT_FORMDATA_REPRESENTATION_NAME);
}
@Test
void shouldReturnDefaultOnMissingPrimary() {
var control = FormDataControlTestFactory.createBuilder().representations(Optional.of(Representations.builder().build())).build();
var result = adapter.getEntryPoint(control);
assertThat(result).isEqualTo(FimBasedAdapter.DEFAULT_FORMDATA_REPRESENTATION_NAME);
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment