From ab9d2ae89e621cd73866e6b2c6cc7f55efd47026 Mon Sep 17 00:00:00 2001 From: i302705 Date: Fri, 11 Sep 2026 16:27:23 +0300 Subject: [PATCH] fix: Use EDMX providers for loading OData API definitions --- .../OrdResourcesProviderConfiguration.java | 1 + .../impl/DynamicOrdResourcesProviderImpl.java | 16 +++- .../impl/StaticOrdResourcesProviderImpl.java | 15 +++- .../DynamicOrdResourcesProviderImplTest.java | 75 ++++++++++++++----- .../StaticOrdResourcesProviderImplTest.java | 51 +++++++++---- 5 files changed, 126 insertions(+), 32 deletions(-) diff --git a/cds-feature-ord/src/main/java/com/sap/cds/feature/ord/configuration/OrdResourcesProviderConfiguration.java b/cds-feature-ord/src/main/java/com/sap/cds/feature/ord/configuration/OrdResourcesProviderConfiguration.java index 03a5b50..dc81ce1 100644 --- a/cds-feature-ord/src/main/java/com/sap/cds/feature/ord/configuration/OrdResourcesProviderConfiguration.java +++ b/cds-feature-ord/src/main/java/com/sap/cds/feature/ord/configuration/OrdResourcesProviderConfiguration.java @@ -27,6 +27,7 @@ public void providers(CdsRuntimeConfigurer configurer) { if (dynamicModelUtils.isModelProviderEnabled()) { configurer.provider(new DynamicOrdResourcesProviderImpl( + cdsRuntime, new MtxSidecarClientImpl(cdsRuntime), dynamicModelUtils, asList(loadAll(CdsOrdNodeProcessor.class, cdsRuntime)))); diff --git a/cds-feature-ord/src/main/java/com/sap/cds/feature/ord/provider/impl/DynamicOrdResourcesProviderImpl.java b/cds-feature-ord/src/main/java/com/sap/cds/feature/ord/provider/impl/DynamicOrdResourcesProviderImpl.java index 8005c91..bbffe05 100644 --- a/cds-feature-ord/src/main/java/com/sap/cds/feature/ord/provider/impl/DynamicOrdResourcesProviderImpl.java +++ b/cds-feature-ord/src/main/java/com/sap/cds/feature/ord/provider/impl/DynamicOrdResourcesProviderImpl.java @@ -6,10 +6,14 @@ import static com.sap.cds.feature.ord.common.Constants.PERSPECTIVE_SYSTEM_INSTANCE; import static com.sap.cds.feature.ord.common.Utils.Resources.asOrdJsonInputStream; import static java.nio.charset.StandardCharsets.UTF_8; +import static org.apache.commons.io.FilenameUtils.getBaseName; +import static org.apache.commons.io.FilenameUtils.getExtension; +import com.sap.cds.adapter.edmx.EdmxV4Provider; import com.sap.cds.feature.ord.clients.MtxSidecarClient; import com.sap.cds.feature.ord.processor.CdsOrdNodeProcessor; import com.sap.cds.feature.ord.provider.OrdResourcesProvider; +import com.sap.cds.services.runtime.CdsRuntime; import com.sap.cds.services.utils.model.DynamicModelUtils; import java.io.ByteArrayInputStream; import java.io.InputStream; @@ -20,8 +24,10 @@ @RequiredArgsConstructor public class DynamicOrdResourcesProviderImpl implements OrdResourcesProvider { + private static final String EDMX_EXTENSION = "edmx"; private static final String ORD_DOCUMENT_PATH = "documents/ord-document"; + private final CdsRuntime cdsRuntime; private final MtxSidecarClient mtxSidecarClient; private final DynamicModelUtils dynamicModelUtils; private final List cdsOrdNodeProcessors; @@ -36,10 +42,18 @@ public void setPrevious(OrdResourcesProvider previous) { @Override public InputStream read(String resource, String perspective) { return !dynamicModelUtils.useStaticModel() && Objects.equals(PERSPECTIVE_SYSTEM_INSTANCE, perspective) - ? loadFromMTXSidecar(resource) + ? this.loadResource(resource) : this.previous.read(resource, perspective); } + private InputStream loadResource(String resource) { + if (EDMX_EXTENSION.equalsIgnoreCase(getExtension(resource))) { + return cdsRuntime.getProvider(EdmxV4Provider.class).getEdmx(getBaseName(resource)); + } + + return this.loadFromMTXSidecar(resource); + } + private InputStream loadFromMTXSidecar(String resource) { return Objects.equals(ORD_DOCUMENT_PATH, resource) ? asOrdJsonInputStream( diff --git a/cds-feature-ord/src/main/java/com/sap/cds/feature/ord/provider/impl/StaticOrdResourcesProviderImpl.java b/cds-feature-ord/src/main/java/com/sap/cds/feature/ord/provider/impl/StaticOrdResourcesProviderImpl.java index 9702939..3eced42 100644 --- a/cds-feature-ord/src/main/java/com/sap/cds/feature/ord/provider/impl/StaticOrdResourcesProviderImpl.java +++ b/cds-feature-ord/src/main/java/com/sap/cds/feature/ord/provider/impl/StaticOrdResourcesProviderImpl.java @@ -9,8 +9,11 @@ import static com.sap.cds.feature.ord.common.Utils.Resources.getResourceAsStream; import static java.util.Objects.nonNull; import static org.apache.commons.io.FilenameUtils.concat; +import static org.apache.commons.io.FilenameUtils.getBaseName; +import static org.apache.commons.io.FilenameUtils.getExtension; import static org.apache.commons.io.FilenameUtils.normalize; +import com.sap.cds.adapter.edmx.EdmxV4Provider; import com.sap.cds.feature.ord.processor.CdsOrdNodeProcessor; import com.sap.cds.feature.ord.provider.OrdResourcesProvider; import com.sap.cds.services.runtime.CdsRuntime; @@ -22,6 +25,8 @@ @RequiredArgsConstructor public class StaticOrdResourcesProviderImpl implements OrdResourcesProvider { + private static final String EDMX_EXTENSION = "edmx"; + private final CdsRuntime cdsRuntime; private final List cdsOrdNodeProcessors; @@ -38,6 +43,14 @@ public InputStream read(String resource, String perspective) { return Objects.equals("documents/ord-document", normalized) ? asOrdJsonInputStream(getResourceAsStream(ordDocumentAbsolutePath), cdsOrdNodeProcessors) - : getResourceAsStream(concat(ordResourcesRoot, normalized)); + : loadResourceAsStream(concat(ordResourcesRoot, normalized)); + } + + private InputStream loadResourceAsStream(String path) { + if (EDMX_EXTENSION.equalsIgnoreCase(getExtension(path))) { + return cdsRuntime.getProvider(EdmxV4Provider.class).getEdmx(getBaseName(path)); + } + + return getResourceAsStream(path); } } diff --git a/cds-feature-ord/src/test/java/com/sap/cds/feature/ord/provider/impl/DynamicOrdResourcesProviderImplTest.java b/cds-feature-ord/src/test/java/com/sap/cds/feature/ord/provider/impl/DynamicOrdResourcesProviderImplTest.java index fb4bb37..21b45ed 100644 --- a/cds-feature-ord/src/test/java/com/sap/cds/feature/ord/provider/impl/DynamicOrdResourcesProviderImplTest.java +++ b/cds-feature-ord/src/test/java/com/sap/cds/feature/ord/provider/impl/DynamicOrdResourcesProviderImplTest.java @@ -6,12 +6,14 @@ import static com.sap.cds.feature.ord.common.Constants.PERSPECTIVE_SYSTEM_INSTANCE; import static com.sap.cds.feature.ord.common.Constants.PERSPECTIVE_SYSTEM_VERSION; import static java.nio.charset.StandardCharsets.UTF_8; +import static org.apache.commons.io.IOUtils.toInputStream; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; +import com.sap.cds.adapter.edmx.EdmxV4Provider; import com.sap.cds.feature.ord.clients.MtxSidecarClient; import com.sap.cds.feature.ord.provider.OrdResourcesProvider; import com.sap.cds.services.environment.CdsEnvironment; @@ -31,6 +33,7 @@ class DynamicOrdResourcesProviderImplTest { private CdsRuntime cdsRuntime; private CdsProperties cdsProperties; private CdsEnvironment cdsEnvironment; + private EdmxV4Provider edmxV4Provider; private MtxSidecarClient mtxSidecarClient; private DynamicModelUtils dynamicModelUtils; private OrdResourcesProvider ordResourcesProvider; @@ -43,16 +46,19 @@ void setUp() { cdsRuntime = mock(CdsRuntime.class); cdsProperties = mock(CdsProperties.class); cdsEnvironment = mock(CdsEnvironment.class); + edmxV4Provider = mock(EdmxV4Provider.class); mtxSidecarClient = mock(MtxSidecarClient.class); dynamicModelUtils = mock(DynamicModelUtils.class); ordResourcesProvider = mock(OrdResourcesProvider.class); openResourceDiscovery = mock(OpenResourceDiscovery.class); - classUnderTest = new DynamicOrdResourcesProviderImpl(mtxSidecarClient, dynamicModelUtils, List.of()); + classUnderTest = + new DynamicOrdResourcesProviderImpl(cdsRuntime, mtxSidecarClient, dynamicModelUtils, List.of()); classUnderTest.setPrevious(ordResourcesProvider); doReturn(cdsEnvironment).when(cdsRuntime).getEnvironment(); doReturn(openResourceDiscovery).when(cdsProperties).getOrd(); doReturn(cdsProperties).when(cdsEnvironment).getCdsProperties(); + doReturn(edmxV4Provider).when(cdsRuntime).getProvider(EdmxV4Provider.class); } @Test @@ -73,10 +79,11 @@ void givenThatStaticModelShouldBeUsed_and_perspectiveIsSystemVersion_whenReadIsC cdsRuntime, cdsProperties, cdsEnvironment, + edmxV4Provider, mtxSidecarClient, dynamicModelUtils, - openResourceDiscovery, - ordResourcesProvider); + ordResourcesProvider, + openResourceDiscovery); } @Test @@ -97,10 +104,11 @@ void givenThatStaticModelShouldBeUsed_and_perspectiveIsSystemInstance_whenReadIs cdsRuntime, cdsProperties, cdsEnvironment, + edmxV4Provider, mtxSidecarClient, dynamicModelUtils, - openResourceDiscovery, - ordResourcesProvider); + ordResourcesProvider, + openResourceDiscovery); } @Test @@ -122,10 +130,11 @@ void givenThatStaticModelShouldBeUsed_and_perspectiveIsSystemInstance_whenReadIs cdsRuntime, cdsProperties, cdsEnvironment, + edmxV4Provider, mtxSidecarClient, dynamicModelUtils, - openResourceDiscovery, - ordResourcesProvider); + ordResourcesProvider, + openResourceDiscovery); } @Test @@ -145,10 +154,11 @@ void givenThatStaticModelShouldBeUsed_and_perspectiveIsSystemInstance_whenReadIs cdsRuntime, cdsProperties, cdsEnvironment, + edmxV4Provider, mtxSidecarClient, dynamicModelUtils, - openResourceDiscovery, - ordResourcesProvider); + ordResourcesProvider, + openResourceDiscovery); } @Test @@ -172,10 +182,11 @@ void givenThatStaticModelShouldBeUsed_and_perspectiveIsSystemInstance_whenReadIs cdsRuntime, cdsProperties, cdsEnvironment, + edmxV4Provider, mtxSidecarClient, dynamicModelUtils, - openResourceDiscovery, - ordResourcesProvider); + ordResourcesProvider, + openResourceDiscovery); } @Test @@ -199,10 +210,11 @@ void givenThatStaticModelShouldBeUsed_and_perspectiveIsSystemInstance_whenReadIs cdsRuntime, cdsProperties, cdsEnvironment, + edmxV4Provider, mtxSidecarClient, dynamicModelUtils, - openResourceDiscovery, - ordResourcesProvider); + ordResourcesProvider, + openResourceDiscovery); } @Test @@ -224,10 +236,11 @@ void givenThatStaticModelShouldBeUsed_and_perspectiveIsSystemInstance_whenReadIs cdsRuntime, cdsProperties, cdsEnvironment, + edmxV4Provider, mtxSidecarClient, dynamicModelUtils, - openResourceDiscovery, - ordResourcesProvider); + ordResourcesProvider, + openResourceDiscovery); } @Test @@ -251,9 +264,37 @@ void givenThatStaticModelShouldBeUsed_and_perspectiveIsSystemInstance_whenReadIs cdsRuntime, cdsProperties, cdsEnvironment, + edmxV4Provider, mtxSidecarClient, dynamicModelUtils, - openResourceDiscovery, - ordResourcesProvider); + ordResourcesProvider, + openResourceDiscovery); + } + + @Test + void + givenThatDynamicModelShouldBeUsed_and_perspectiveIsSystemInstance_and_edmxResourceDefinitionIsRequested_whenReadIsCalled_thenCorrectResultIsReturned() + throws IOException { + doReturn(false).when(dynamicModelUtils).useStaticModel(); + doReturn(toInputStream("", UTF_8)).when(edmxV4Provider).getEdmx("test"); + doReturn("ord/").when(openResourceDiscovery).getOrdResourcesRoot(); + + assertEquals( + "", + IOUtils.toString( + classUnderTest.read("test:ord:service/test.edmx", PERSPECTIVE_SYSTEM_INSTANCE), UTF_8)); + + verify(dynamicModelUtils).useStaticModel(); + verify(edmxV4Provider).getEdmx("test"); + verify(cdsRuntime).getProvider(EdmxV4Provider.class); + verifyNoMoreInteractions( + cdsRuntime, + cdsProperties, + cdsEnvironment, + edmxV4Provider, + mtxSidecarClient, + dynamicModelUtils, + ordResourcesProvider, + openResourceDiscovery); } } diff --git a/cds-feature-ord/src/test/java/com/sap/cds/feature/ord/provider/impl/StaticOrdResourcesProviderImplTest.java b/cds-feature-ord/src/test/java/com/sap/cds/feature/ord/provider/impl/StaticOrdResourcesProviderImplTest.java index 239cc10..b4e49da 100644 --- a/cds-feature-ord/src/test/java/com/sap/cds/feature/ord/provider/impl/StaticOrdResourcesProviderImplTest.java +++ b/cds-feature-ord/src/test/java/com/sap/cds/feature/ord/provider/impl/StaticOrdResourcesProviderImplTest.java @@ -6,20 +6,29 @@ import static com.sap.cds.feature.ord.common.Constants.PERSPECTIVE_SYSTEM_INSTANCE; import static com.sap.cds.feature.ord.common.Constants.PERSPECTIVE_SYSTEM_VERSION; import static com.sap.cds.feature.ord.common.Utils.CdsRuntimeProperties.getOrdProperties; +import static com.sap.cds.services.runtime.CdsRuntimeConfigurer.create; +import static java.nio.charset.StandardCharsets.UTF_8; import static org.apache.commons.io.FilenameUtils.concat; import static org.apache.commons.io.FilenameUtils.getBaseName; +import static org.apache.commons.io.IOUtils.toInputStream; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import com.sap.cds.adapter.edmx.EdmxV4Provider; import com.sap.cds.impl.parser.JsonParser; import com.sap.cds.services.runtime.CdsRuntime; -import com.sap.cds.services.runtime.CdsRuntimeConfigurer; +import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.List; import java.util.Map; +import org.apache.commons.io.IOUtils; import org.junit.jupiter.api.Test; @SuppressWarnings("unchecked") @@ -27,11 +36,10 @@ class StaticOrdResourcesProviderImplTest { @Test void givenPerspectiveIsNull_whenGetDocumentIsCalled_thenCorrectResultIsReturned() { - CdsRuntime runtime = CdsRuntimeConfigurer.create().complete(); - StaticOrdResourcesProviderImpl provider = new StaticOrdResourcesProviderImpl(runtime, List.of()); + CdsRuntime runtime = create().complete(); String document = concat("documents", getBaseName(getOrdProperties(runtime).getOrdDocumentPath())); - InputStream is = provider.read(document, null); + InputStream is = new StaticOrdResourcesProviderImpl(runtime, List.of()).read(document, null); assertNotNull(is); @@ -50,11 +58,11 @@ void givenPerspectiveIsNull_whenGetDocumentIsCalled_thenCorrectResultIsReturned( @Test void givenPerspectiveIsSystemVersion_whenGetDocumentIsCalled_thenCorrectResultIsReturned() { - CdsRuntime runtime = CdsRuntimeConfigurer.create().complete(); - StaticOrdResourcesProviderImpl provider = new StaticOrdResourcesProviderImpl(runtime, List.of()); + CdsRuntime runtime = create().complete(); String document = concat("documents", getBaseName(getOrdProperties(runtime).getOrdDocumentPath())); - InputStream is = provider.read(document, PERSPECTIVE_SYSTEM_VERSION); + InputStream is = + new StaticOrdResourcesProviderImpl(runtime, List.of()).read(document, PERSPECTIVE_SYSTEM_VERSION); assertNotNull(is); @@ -73,19 +81,36 @@ void givenPerspectiveIsSystemVersion_whenGetDocumentIsCalled_thenCorrectResultIs @Test void givenPerspectiveIsSystemInstance_whenGetDocumentIsCalled_thenCorrectResultIsReturned() { - CdsRuntime runtime = CdsRuntimeConfigurer.create().complete(); - StaticOrdResourcesProviderImpl provider = new StaticOrdResourcesProviderImpl(runtime, List.of()); + CdsRuntime runtime = create().complete(); String document = concat("documents", getBaseName(getOrdProperties(runtime).getOrdDocumentPath())); - assertThrows(IllegalArgumentException.class, () -> provider.read(document, PERSPECTIVE_SYSTEM_INSTANCE)); + assertThrows(IllegalArgumentException.class, () -> new StaticOrdResourcesProviderImpl(runtime, List.of()) + .read(document, PERSPECTIVE_SYSTEM_INSTANCE)); } @Test void givenThatDocumentDoesNotExist_whenGetDocumentIsCalled_thenNullIsReturned() { - CdsRuntime runtime = CdsRuntimeConfigurer.create().complete(); - StaticOrdResourcesProviderImpl provider = new StaticOrdResourcesProviderImpl(runtime, List.of()); + assertNull(new StaticOrdResourcesProviderImpl(create().complete(), List.of()) + .read("no-such-ord-document.json", null)); + } - assertNull(provider.read("no-such-ord-document.json", null)); + @Test + void givenPerspectiveIsSystemVersion_and_edmxResource_whenGetDocumentIsCalled_thenCorrectResultIsReturned() + throws IOException { + EdmxV4Provider edmxV4Provider = mock(EdmxV4Provider.class); + doReturn(toInputStream("", UTF_8)).when(edmxV4Provider).getEdmx("test"); + + assertEquals( + "", + IOUtils.toString( + new StaticOrdResourcesProviderImpl( + create().provider(edmxV4Provider).complete(), List.of()) + .read("documents/test_ord_service/test.edmx", PERSPECTIVE_SYSTEM_VERSION), + UTF_8)); + + verify(edmxV4Provider).setPrevious(null); + verify(edmxV4Provider).getEdmx("test"); + verifyNoMoreInteractions(edmxV4Provider); } }