简体   繁体   English

VDM适用于一项Odata服务,不适用于另一项Odata服务

[英]VDM works for one Odata service, doesn't work for another

I tried to use S4 SDK to connect to S/4 HANA Odata service. 我试图使用S4 SDK连接到S / 4 HANA Odata服务。 S/4 team gave us two services. S / 4团队为我们提供了两项服务。 With same destination, similar code, integration with one service works, with another doesn't. 在相同的目的地,相似的代码,与一种服务的集成有效,而与另一种服务的集成无效。

Best regards 最好的祝福

Ying

code used is 使用的代码是

final List<User> userList = new DefaultS4cUserMetadataService()
        .getAllUser()
        .select(
            User.USER, 
            User.BUSINESS_UNIT,
            User.COMPANY,
            User.COST_CENTER) 
        .filter(
            User.TIME_STAMP.ge(LocalDateTime.of(1970, Month.JANUARY, 1, 0, 0, 0)))
        .orderBy(User.USER, Order.ASC)
        .execute(configContext);
return userList;

I also called without select and filter, but it get the same error: Internal error with code 500. But for the service to get business role, it worked. 我还调用了没有select和filter的方法,但是它得到了相同的错误:代码为500的内部错误。但是对于获得业务角色的服务而言,它却起作用了。 The code used to get business role is 获得业务角色的代码是

final List<IAGBusinessRoleView> businessRoleList =
        new DefaultS4cBusinessRoleMetadataService()
            .getAllIAGBusinessRoleView()
            .select(
                IAGBusinessRoleView.BUS_ROLE_ID,
                IAGBusinessRoleView.USER_NAME,
                IAGBusinessRoleView.UUID,
                IAGBusinessRoleView.DESCRIPTION,
                IAGBusinessRoleView.TIME_STAMP,
                IAGBusinessRoleView.LANGUAGE_KEY)
            .orderBy(IAGBusinessRoleView.BUS_ROLE_ID, Order.ASC)
            .execute(configContext);
return businessRoleList;

It used the same destination. 它使用了相同的目的地。

After looking at the problem we found out the S/4HANA service in the background did not behave as expected. 在查看了问题之后,我们发现后台的S / 4HANA服务没有按预期运行。

Fur further reference I will describe a way to understand what happens under the hood of the OData VDM. 进一步的参考,我将描述一种了解OData VDM幕后发生情况的方法。


Making the HTTP calls visible 使HTTP调用可见

To see what HTTP requests the OData VDM executes we will build a test which sets up and tears down a local mock server to which the requests will be sent. 为了查看OData VDM执行的HTTP请求,我们将构建一个测试来设置和拆除将请求发送到的本地模拟服务器。 For that we use Wiremock . 为此,我们使用Wiremock

Prerequisites 先决条件

The only prerequisite for this is that you download the metadata file of the service you want to test against. 唯一的前提条件是下载要测试的服务的元数据文件。 You can obtain this by using the $metadata endpoint of your target system. 您可以使用目标系统的$metadata端点来获取此信息。

For the PhysicalInventoryDocumentService this might look something like this: 对于PhysicalInventoryDocumentService它可能看起来像这样:

https://myserver.com/sap/opu/odata/sap/API_PHYSICAL_INVENTORY_DOC_SRV/$metadata

The path can be found in the service interface of your service to check. 可以在您的服务的服务界面中找到该路径以进行检查。 In this example you will find it in the PhysicalInventoryDocumentService : 在此示例中,您可以在PhysicalInventoryDocumentService找到它:

public interface PhysicalInventoryDocumentService
{
    // ...
    String DEFAULT_SERVICE_PATH = "/sap/opu/odata/sap/API_PHYSICAL_INVENTORY_DOC_SRV";
    // ...
}

Setup the Test 设置测试

Create a normal test class inside your test directory ( SomeTest in this example). 在您的测试目录(此示例中为SomeTest )内创建一个普通的测试类。

Move the metadata file you downloaded in the previous step into your test-resources directory in a subdirectory named after you test. 将您在上一步中下载的元数据文件移动到测试后命名的子目录中的test-resources目录中。 So in my example I have the following structure: src->test->resources->SomeTest->API_PHYSICAL_INVENTORY_DOC_SRV.edmx . 因此,在我的示例中,我具有以下结构: src->test->resources->SomeTest->API_PHYSICAL_INVENTORY_DOC_SRV.edmx

In your test class add the following lines on the class level: 在测试类中,在类级别上添加以下行:

private static final MockUtil mockUtil = new MockUtil();
@Rule
public final WireMockRule erpServer = mockUtil.mockErpServer();

This will, for every test method, set up a mock server, execute the code, and finally tear the server down again. 对于每种测试方法,这将设置一个模拟服务器,执行代码,最后再次关闭服务器。 The MockUtil can be found in the com.sap.cloud.s4hana:testutil library of the S/4HANA Cloud SDK. MockUtil可以在找到com.sap.cloud.s4hana:testutil的S / 4HANA云SDK库。

Then add the following setUp method: 然后添加以下setUp方法:

@Before
public void setUp()
{
    final String metadataAsString =
        TestUtil.readResourceFile(SomeTest.class, "API_PHYSICAL_INVENTORY_DOC_SRV.edmx");
    stubFor(
        get(urlEqualTo("/sap/opu/odata/sap/API_PHYSICAL_INVENTORY_DOC_SRV/$metadata"))
            .willReturn(okXml(metadataAsString)));
}

There you need to replace the class name, the metadata filename, and the url to the one from your service. 您需要在其中替换类名称,元数据文件名以及服务中的URL。 These lines will tell the mock server to return the metadata if a request is received on the given URL. 这些行将告诉模拟服务器如果在给定URL上收到请求,则返回元数据。 As this is first step of every OData VDM call this needs to be mocked. 由于这是每个OData VDM调用的第一步,因此需要对其进行模拟。

Now create a test method as follows: 现在创建如下的测试方法:

@Test
public void testSomething()
    throws ODataException
{
    new DefaultPhysicalInventoryDocumentService().getAllPhysInventoryDocItem().execute();
}

You need to replace the call here with the one you want to actually test/verify. 您需要将此处的呼叫替换为您要实际测试/验证的呼叫。

Run the Test 运行测试

If you run the test you will receive an error message containing the following table: 如果运行测试,您将收到包含下表的错误消息:

[qtp1038820134-18] ERROR WireMock - 
                                               Request was not matched
                                               =======================

-----------------------------------------------------------------------------------------------------------------------
| Closest stub                                             | Request                                                  |
-----------------------------------------------------------------------------------------------------------------------
                                                           |
GET                                                        | GET
/sap/opu/odata/sap/API_PHYSICAL_INVENTORY_DOC_SRV/$metada  | /sap/opu/odata/sap/API_PHYSICAL_INVENTORY_DOC_SRV/A_PhysI<<<<< URL does not match
ta                                                         | nventoryDocItem?$format=json
                                                           |
                                                           |
-----------------------------------------------------------------------------------------------------------------------

This is the usual Wiremock response if the server received a request that was not mocked. 如果服务器收到未模拟的请求,这是通常的Wiremock响应。 On the left you see the closest mocked requst and on the right the actually received request. 在左侧,您可以看到最接近的模拟请求,而在右侧,您可以看到实际收到的请求。

You can now use the request on the right via Postman or your browser and verify the behavior directly. 现在,您可以通过Postman或浏览器使用右侧的请求,并直接验证行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM