diff --git a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimSchemeCatalogue.java b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimSchemeCatalogue.java index e6dab27a01114ec9e70d4bff1bd9d3e7037da9c9..bdf965588c5e53b1da6ce0c81ca10852482d7828 100644 --- a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimSchemeCatalogue.java +++ b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimSchemeCatalogue.java @@ -1,8 +1,97 @@ package de.ozgcloud.eingang.fim; +import java.io.File; +import java.io.IOException; import java.util.LinkedHashMap; -class FimSchemeCatalogue extends LinkedHashMap<FimSchemeIdentifier, FimScheme> { +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.springframework.core.io.ResourceLoader; +import org.w3c.dom.Document; +import org.xml.sax.SAXException; + +import de.ozgcloud.eingang.common.errorhandling.TechnicalException; +import lombok.extern.log4j.Log4j2; + +@Log4j2 +class FimSchemeCatalogue extends LinkedHashMap<FimSchemeIdentifier, FimScheme> { // NOSONAR private static final long serialVersionUID = 1L; -} + + private final transient FimProperties fimProperties; + private final transient ResourceLoader resourceLoader; + private final transient FimSchemeAdapterCatalogue adapterCatalogue; + + private static final FimSchemeAdapter DEFAULT_FIM_SCHEME_ADAPTER = new FimSchemeAdapter() { + @Override + public FimSchemeIdentifier getIdentifier() { + return null; + } + }; + + public FimSchemeCatalogue(FimProperties fimProperties, ResourceLoader resourceLoader, FimSchemeAdapterCatalogue adapterCatalogue) { + this.fimProperties = fimProperties; + this.resourceLoader = resourceLoader; + this.adapterCatalogue = adapterCatalogue; + + initSchemes(); + } + + private void initSchemes() { + try { + initScheme(); + + initUnknownScheme(); + } catch (ParserConfigurationException | IOException | SAXException e) { + throw new TechnicalException("Error on initalising FimSchemes.", e); + } + } + + private void initScheme() throws ParserConfigurationException, IOException, SAXException { + for (var fimSchemaLocation : fimProperties.getSchemeLocations()) { + put(loadFimScheme(fimSchemaLocation.trim())); + } + } + + private void initUnknownScheme() throws ParserConfigurationException { + put(createScheme(createDocumentBuilder().newDocument(), UnknownSchemeAdapter.UNKNOWN_SCHEME_NAME)); + } + + private FimScheme loadFimScheme(String path) throws ParserConfigurationException, IOException, SAXException { + LOG.debug("Load FIM schema: " + path); + var doc = createDocumentBuilder().parse(getFile(path)); + return createScheme(doc, getTargetNamespace(doc)); + } + + private void put(FimScheme scheme) { + this.put(scheme.getIdentifier(), scheme); + } + + private DocumentBuilder createDocumentBuilder() throws ParserConfigurationException { + return DocumentBuilderFactory.newInstance().newDocumentBuilder(); + } + + private File getFile(String path) throws IOException { + return resourceLoader.getResource("classpath:" + path).getFile(); + } + + private String getTargetNamespace(Document doc) { + return doc.getDocumentElement().getAttribute("targetNamespace"); + } + + private FimScheme createScheme(Document doc, String identifierName) { + var identifier = getIdentifierFromString(identifierName); + var adapter = getFimSchemeAdapter(identifier); + return new FimScheme(doc, identifier, adapter); + } + + private FimSchemeIdentifier getIdentifierFromString(String name) { + return FimSchemeIdentifier.fromString(name); + } + + private FimSchemeAdapter getFimSchemeAdapter(FimSchemeIdentifier identifier) { + return adapterCatalogue.getOrDefault(identifier, DEFAULT_FIM_SCHEME_ADAPTER); + } +} \ No newline at end of file diff --git a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimSchemeHelper.java b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimSchemeHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..116f35040eec4edf768399357e93314f0fc736df --- /dev/null +++ b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimSchemeHelper.java @@ -0,0 +1,48 @@ +package de.ozgcloud.eingang.fim; + +import java.util.List; +import java.util.Objects; + +import jakarta.annotation.PostConstruct; + +import org.springframework.core.io.ResourceLoader; +import org.springframework.stereotype.Component; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Component +class FimSchemeHelper { + + private final FimProperties fimProperties; + private final ResourceLoader resourceLoader; + private final List<FimSchemeAdapter> fimSchemeAdapters; + + private FimSchemeAdapterCatalogue schemeAdapterCatalogue; + private FimSchemeCatalogue schemeCatalogue; + + @PostConstruct + void init() { + initSchemeAdapterCatalogue(); + initSchemeCatalogue(); + } + + private void initSchemeAdapterCatalogue() { + schemeAdapterCatalogue = new FimSchemeAdapterCatalogue(); + if (Objects.nonNull(fimSchemeAdapters)) { + fimSchemeAdapters.forEach(adapter -> schemeAdapterCatalogue.put(adapter.getIdentifier(), adapter)); + } + } + + private void initSchemeCatalogue() { + schemeCatalogue = new FimSchemeCatalogue(fimProperties, resourceLoader, schemeAdapterCatalogue); + } + + public FimScheme getScheme(String identifier) { + return schemeCatalogue.get(FimSchemeIdentifier.fromString(identifier)); + } + + public FimScheme getDefaultScheme() { + return schemeCatalogue.get(UnknownSchemeAdapter.IDENTIFIER); + } +} \ No newline at end of file diff --git a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimService.java b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimService.java index da5ad07ca9c864efcd3fae2d4a48eef7ac354482..447bf27985d0b08ad00abc3c4e0e164b29370507 100644 --- a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimService.java +++ b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/FimService.java @@ -1,112 +1,28 @@ package de.ozgcloud.eingang.fim; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; import java.util.Objects; import java.util.Optional; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - -import jakarta.annotation.PostConstruct; - -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 de.ozgcloud.eingang.common.formdata.FormData; import de.ozgcloud.eingang.common.formdata.FormHeader; import de.ozgcloud.eingang.fim.common.errorhandling.FimException; import io.micrometer.common.util.StringUtils; +import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; @Log4j2 +@RequiredArgsConstructor @Service public class FimService { - public static final String UNKNOWN_SCHEME_NAME = "unknown"; - - @Autowired - private FimProperties fimProperties; - - @Autowired - private FimDataMapper fimDataMapper; - - @Autowired - private ResourceLoader resourceLoader; - @Autowired - private AntragstellerMapper antragstellerMapper; - - @Autowired - private final List<FimSchemeAdapter> fimSchemeAdapters = new ArrayList<>(); - - private final FimSchemeCatalogue fimSchemeCatalogue = new FimSchemeCatalogue(); - private final FimSchemeAdapterCatalogue fimSchemeAdapterCatalogue = new FimSchemeAdapterCatalogue(); - - private static final FimSchemeAdapter DEFAULT_FIM_SCHEME_ADAPTER = new FimSchemeAdapter() { - @Override - public FimSchemeIdentifier getIdentifier() { - return null; - } - }; - - @PostConstruct - private void postConstruct() throws ParserConfigurationException, IOException, SAXException { - initFimSchemeAdapterCatalogue(); - initFimSchemeCatalogue(); - - initUnknownScheme(); - } - - private void initFimSchemeAdapterCatalogue() { - fimSchemeAdapters.forEach(adapter -> fimSchemeAdapterCatalogue.put(adapter.getIdentifier(), adapter)); - } - - private void initFimSchemeCatalogue() throws ParserConfigurationException, IOException, SAXException { - for (var fimSchemaLocation : fimProperties.getSchemeLocations()) { - var fimScheme = loadFimScheme(fimSchemaLocation.trim()); - fimSchemeCatalogue.put(fimScheme.getIdentifier(), fimScheme); - } - } - private void initUnknownScheme() throws ParserConfigurationException { - var unknownScheme = createScheme(createDocumentBuilder().newDocument(), UNKNOWN_SCHEME_NAME); - fimSchemeCatalogue.put(unknownScheme.getIdentifier(), unknownScheme); - } - - private FimScheme loadFimScheme(final String path) throws ParserConfigurationException, IOException, SAXException { - LOG.debug("Load FIM schema: " + path); - var doc = createDocumentBuilder().parse(getFile(path)); - return createScheme(doc, getTargetNamespace(doc)); - } - - private DocumentBuilder createDocumentBuilder() throws ParserConfigurationException { - return DocumentBuilderFactory.newInstance().newDocumentBuilder(); - } - - private File getFile(String path) throws IOException { - return resourceLoader.getResource("classpath:" + path).getFile(); - } - - private String getTargetNamespace(Document doc) { - return doc.getDocumentElement().getAttribute("targetNamespace"); - } + private final FimDataMapper fimDataMapper; + private final AntragstellerMapper antragstellerMapper; + private final FimSchemeHelper schemeCatalogueHelper; - private FimScheme createScheme(Document doc, String identifierName) { - var identifier = getIdentifierFromString(identifierName); - var adapter = getFimSchemeAdapter(identifier); - return new FimScheme(doc, identifier, adapter); - } - - private FimSchemeIdentifier getIdentifierFromString(String name) { - return FimSchemeIdentifier.fromString(name); - } - - public FormData transformDocument(final Document document, final FormData initialFormData) { + public FormData transformDocument(Document document, FormData initialFormData) { var schemeName = getSchemeName(document); if (StringUtils.isEmpty(schemeName)) { throw new FimException("XML Document does not provide a scheme"); @@ -119,30 +35,22 @@ public class FimService { .build(); } - private String getSchemeName(Document doc) { + private static String getSchemeName(Document doc) { var tagParts = doc.getDocumentElement().getTagName().split(":"); var namespacePrefix = tagParts.length < 2 ? "" : (":" + tagParts[0]); return doc.getDocumentElement().getAttribute("xmlns" + namespacePrefix); } FimScheme getSchemeForIdentifier(String fimSchemaName) { - var fimScheme = getFimScheme(FimSchemeIdentifier.fromString(fimSchemaName)); + var fimScheme = schemeCatalogueHelper.getScheme(fimSchemaName); if (Objects.isNull(fimScheme)) { LOG.error("Cannot find schema for: " + fimSchemaName); - return getFimScheme(FimSchemeIdentifier.fromString(UNKNOWN_SCHEME_NAME)); + return schemeCatalogueHelper.getDefaultScheme(); } return fimScheme; } - private FimScheme getFimScheme(FimSchemeIdentifier identifier) { - return fimSchemeCatalogue.get(identifier); - } - - private FimSchemeAdapter getFimSchemeAdapter(FimSchemeIdentifier identifier) { - return fimSchemeAdapterCatalogue.getOrDefault(identifier, DEFAULT_FIM_SCHEME_ADAPTER); - } - private FormHeader buildFormHeader(FormData formData) { return formData.getHeader().toBuilder() .formName(getVorgangsName(formData).orElse(null)) diff --git a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/UnknownSchemeAdapter.java b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/UnknownSchemeAdapter.java index e10e926957d61b73e7c13cf7da4729ee98d6d304..69b20d1af523317fc741083b1ec198334a574afa 100644 --- a/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/UnknownSchemeAdapter.java +++ b/fim-adapter/src/main/java/de/ozgcloud/eingang/fim/UnknownSchemeAdapter.java @@ -1,22 +1,26 @@ package de.ozgcloud.eingang.fim; -import org.springframework.stereotype.Service; -import org.w3c.dom.Element; - import java.util.Map; import java.util.Optional; +import org.springframework.stereotype.Service; +import org.w3c.dom.Element; + @Service -public class UnknownSchemeAdapter extends FimSchemeAdapter { +class UnknownSchemeAdapter extends FimSchemeAdapter { + + public static final String UNKNOWN_SCHEME_NAME = "unknown"; + public static final FimSchemeIdentifier IDENTIFIER = FimSchemeIdentifier.fromString(UNKNOWN_SCHEME_NAME); - public FimSchemeIdentifier getIdentifier() { - return FimSchemeIdentifier.fromString(FimService.UNKNOWN_SCHEME_NAME); - } + @Override + public FimSchemeIdentifier getIdentifier() { + return IDENTIFIER; + } - @Override - public Optional<String> getFieldName(Map<String, Element> fieldIndex, String fieldName) { - final String[] fieldNameParts = fieldName.split(":"); - final String fieldNameWithoutNamespace = fieldNameParts[fieldNameParts.length - 1]; - return Optional.of(fieldNameWithoutNamespace); - } + @Override + public Optional<String> getFieldName(Map<String, Element> fieldIndex, String fieldName) { + var fieldNameParts = fieldName.split(":"); + var fieldNameWithoutNamespace = fieldNameParts[fieldNameParts.length - 1]; + return Optional.of(fieldNameWithoutNamespace); + } } diff --git a/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimSchemeHelperTest.java b/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimSchemeHelperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..9978e286bb6205d6bc7d1662a93a5ee5667e7fbe --- /dev/null +++ b/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimSchemeHelperTest.java @@ -0,0 +1,139 @@ +package de.ozgcloud.eingang.fim; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.springframework.core.io.ResourceLoader; + +import de.ozgcloud.common.test.ReflectionTestUtils; + +class FimSchemeHelperTest { + + @InjectMocks + private FimSchemeHelper helper; + @Mock + private FimProperties fimProperties; + @Mock + private ResourceLoader resourceLoader; + + @DisplayName("Init") + @Nested + class TestInit { + + @DisplayName("scheme adapter catalogue") + @Nested + class TestInitSchemeAdapterCatalogue { + + @Mock + private FimSchemeAdapter adapter; + + @Test + void shouldInitByAdapter() { + setFimSchemeAdapter(); + + helper.init(); + + assertThat(getSchemeAdapterCatalogue()).isNotNull().hasSize(1); + } + + @Test + void shouldInit() { + helper.init(); + + assertThat(getSchemeAdapterCatalogue()).isNotNull().isEmpty(); + } + + private void setFimSchemeAdapter() { + ReflectionTestUtils.setField(helper, "fimSchemeAdapters", List.of(adapter)); + } + + private FimSchemeAdapterCatalogue getSchemeAdapterCatalogue() { + return ReflectionTestUtils.getField(helper, "schemeAdapterCatalogue", FimSchemeAdapterCatalogue.class); + } + } + + @Test + void shouldInitSchemeCatalogue() { + helper.init(); + + assertThat(getSchemeCatalogue()).isNotNull(); + } + + private FimSchemeCatalogue getSchemeCatalogue() { + return ReflectionTestUtils.getField(helper, "schemeCatalogue", FimSchemeCatalogue.class); + } + } + + @DisplayName("Get scheme") + @Nested + class TestGetScheme { + + @Mock + private FimSchemeCatalogue schemeCatalogue; + @Mock + private FimScheme fimScheme; + + private String identifier = "idenditifierName"; + + @BeforeEach + void mock() { + ReflectionTestUtils.setField(helper, "schemeCatalogue", schemeCatalogue); + when(schemeCatalogue.get(any())).thenReturn(fimScheme); + } + + @Test + void shouldCallSchemeCatalogue() { + helper.getScheme(identifier); + + verify(schemeCatalogue).get(FimSchemeIdentifier.fromString(identifier)); + } + + @Test + void shouldReturnScheme() { + var scheme = helper.getScheme(identifier); + + assertThat(scheme).isEqualTo(fimScheme); + } + } + + @DisplayName("Get default scheme") + @Nested + class TestGetDefaultScheme { + + @Mock + private FimSchemeCatalogue schemeCatalogue; + @Mock + private FimSchemeIdentifier identifier; + @Mock + private FimScheme fimScheme; + + @BeforeEach + void mock() { + ReflectionTestUtils.setField(helper, "schemeCatalogue", schemeCatalogue); + when(schemeCatalogue.get(any())).thenReturn(fimScheme); + } + + @Test + void shouldCallSchemeCatalogue() { + helper.getDefaultScheme(); + + verify(schemeCatalogue).get(FimSchemeIdentifier.fromString(UnknownSchemeAdapter.UNKNOWN_SCHEME_NAME)); + } + + @Test + void shouldReturnScheme() { + var scheme = helper.getDefaultScheme(); + + assertThat(scheme).isEqualTo(fimScheme); + } + } +} \ No newline at end of file diff --git a/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimServiceITCase.java b/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimServiceITCase.java index 80267f923f9517aa620f5d9a93e1f0131394286d..76c88666f608eae6d831ca7234ae002f3376c7ff 100644 --- a/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimServiceITCase.java +++ b/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimServiceITCase.java @@ -8,7 +8,6 @@ import java.io.IOException; import java.util.List; import java.util.Map; -import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; @@ -226,7 +225,6 @@ class FimServiceITCase { } private Document loadDocument(final String path) throws ParserConfigurationException, IOException, SAXException { - final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - return builder.parse(new File(path)); + return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File(path)); } } diff --git a/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimTestConfig.java b/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimTestConfig.java index 8e88e6f0ae161bffefca00daaef61bb3871a508a..e5087bb9500a631087c61d75f4a481870cf1587d 100644 --- a/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimTestConfig.java +++ b/fim-adapter/src/test/java/de/ozgcloud/eingang/fim/FimTestConfig.java @@ -7,5 +7,5 @@ import org.springframework.context.annotation.Configuration; @Configuration @EnableAutoConfiguration @ComponentScan("de.ozgcloud.eingang") -public class FimTestConfig { +class FimTestConfig { }