在SAP Cloud SDK中使用Java生成SFSF的VDM:生成的URI错误 [英] Generate VDM for SFSF using Java in SAP Cloud SDK: Generated URI is wrong

查看:140
本文介绍了在SAP Cloud SDK中使用Java生成SFSF的VDM:生成的URI错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试构建一个从SFSF读取信息的应用程序.为此,我使用带有SFSF OData元数据的虚拟数据模型生成器工具(maven插件)来访问系统.我正在按照以下步骤操作:

I'm trying to build an app that reads info from SFSF. For this, I'm using the Virtual Data model generator tool (the maven plugin) with SFSF OData metadata to be able to access the system. I'm following these steps:

  • 通过原型(带有powershell)获取项目:
mvn archetype:generate "-DarchetypeGroupId=com.sap.cloud.sdk.archetypes" "-DarchetypeArtifactId=scp-cf-tomee" "-DarchetypeVersion=RELEASE"

  • 将以下内容添加到application \ pom.xml 在依赖项中:
    • Add the following to the application\pom.xml In dependencies:
    • <dependency>
                  <groupId>org.projectlombok</groupId>
                  <artifactId>lombok</artifactId>
                  <scope>provided</scope>
      </dependency>
      

      在插件中

      <plugin>
          <groupId>com.sap.cloud.sdk.datamodel</groupId>
          <artifactId>odata-generator-maven-plugin</artifactId>
          <version>3.13.0</version>
          <executions>
              <execution>
                  <id>generate-consumption</id>
                  <phase>generate-sources</phase>
                  <goals>
                      <goal>generate</goal>
                  </goals>
                  <configuration>
                      <inputDirectory>${project.basedir}/edmx</inputDirectory>
                      <outputDirectory>${project.build.directory}/vdm</outputDirectory>
                      <defaultBasePath>/odata/v2</defaultBasePath>
                  </configuration>
              </execution>
          </executions>
      </plugin>
      <plugin>
                      <groupId>org.codehaus.mojo</groupId>
                      <artifactId>build-helper-maven-plugin</artifactId>
                      <version>3.0.0</version>
                      <executions>
                          <execution>
                              <phase>generate-sources</phase>
                              <goals>
                                  <goal>add-source</goal>
                              </goals>
                              <configuration>
                                  <sources>
                                      <source>${project.basedir}/vdm</source>
                                  </sources>
                              </configuration>
                          </execution>
          </executions>
      </plugin>
      

      • https://apisalesdemo2.successfactors.eu/中获取OData元数据文件. odata/v2/JobRequisition/$ metadata 并将其放在./application/edmx
      • 创建目标服务(my-destination),并在其中添加一个指向具有基本身份验证的SFSF实例的目标(使用user @ companyId,连接为200:OK)
      • 在manifest.yml中添加目标服务
      • 创建一个Java类以调用目标并获取数据:
        • Get the OData metadata file from https://apisalesdemo2.successfactors.eu/odata/v2/JobRequisition/$metadata and place it in ./application/edmx
        • Create a destination service (my-destination) and add a destination there pointing to my SFSF instance with basic auth (with user@companyId, the connection is 200:OK)
        • Add the destination service in the manifest.yml
        • Create a java class to call the destination and get the data:
        • package com.sap.sdk;
          
          import com.google.gson.Gson;
          import org.slf4j.Logger;
          import org.slf4j.LoggerFactory;
          
          import javax.servlet.ServletException;
          import javax.servlet.annotation.WebServlet;
          import javax.servlet.http.HttpServlet;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;
          import java.io.IOException;
          import java.util.List;
          
          import com.sap.cloud.sdk.cloudplatform.connectivity.DestinationAccessor;
          import com.sap.cloud.sdk.odatav2.connectivity.ODataException;
          
          import com.sap.cloud.sdk.s4hana.connectivity.DefaultErpHttpDestination;
          import com.sap.cloud.sdk.s4hana.connectivity.ErpHttpDestination;
          import com.sap.cloud.sdk.s4hana.datamodel.odata.namespaces.rcmjobrequisition.JobRequisition;
          import com.sap.cloud.sdk.s4hana.datamodel.odata.services.DefaultRCMJobRequisitionService;
          
          
          @WebServlet("/req")
          public class JobReqServlet extends HttpServlet {
          
              private static final long serialVersionUID = 1L;
              private static final Logger logger = LoggerFactory.getLogger(JobReqServlet.class);
          
              private final ErpHttpDestination destination = DestinationAccessor.getDestination("sfsf-sdk-dest").asHttp()
                      .decorate(DefaultErpHttpDestination::new);
          
          
              @Override
              protected void doGet(final HttpServletRequest request, final HttpServletResponse response)
                      throws ServletException, IOException {
                  try {
                      final List<JobRequisition> jobReqs = new DefaultRCMJobRequisitionService()
                          .getAllJobRequisition()
                          .execute(destination);
                      response.setContentType("application/json");
                      response.getWriter().write(new Gson().toJson(jobReqs));
                  } catch (final ODataException e) {
                      logger.error(e.getMessage(), e);
                      response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                      response.getWriter().write(e.getMessage());
                  }
              }
          }
          

          有了这些(我想我什么都没错过),我做到了:

          With all this (I think I'm not missing anything), I do:

          mvn clean install
          

          和:

          cf push
          

          一切正常,hello world servlet正常,但是当我尝试访问/req时,我得到了: 无法执行元数据请求.

          Everything works well, the hello world servlet works, but when I try to access /req, I get a: Unable to execute metadata request.

          但是,我可以看到该应用正在运行SFSF,因为如果我使用该服务的基本路径(在pom.xml中),我会得到404来自SFSF的消息.

          However, I can see that the app is hitting SFSF because if I play with the base path of the service (in the pom.xml) I get 404's coming from SFSF.

          检查所有内容,我在运行VDM生成器时看到以下内容: 1.这是我在pom中给出的基本路径:

          Checking everything, I see this when the VDM generator is running: 1. This is the base path I'm giving in the pom:

          <defaultBasePath>/odata/v2</defaultBasePath>
          

          1. 我可以看到生成器正确选择了该路径:

          [main] INFO com.sap.cloud.sdk.datamodel.odata.generator.DataModelGenerator -   Default base path:              /odata/v2/
          

          1. 但这是生成器处理的内容:

          [main] INFO com.sap.cloud.sdk.datamodel.odata.generator.ODataToVdmGenerator -   Title: RCMJobRequisition
          [main] INFO com.sap.cloud.sdk.datamodel.odata.generator.ODataToVdmGenerator -   Raw URL: /odata/v2/SFODataSet
          [main] INFO com.sap.cloud.sdk.datamodel.odata.generator.ODataToVdmGenerator -   Java Package Name: rcmjobrequisition
          [main] INFO com.sap.cloud.sdk.datamodel.odata.generator.ODataToVdmGenerator -   Java Class Name: RCMJobRequisition
          

          很明显,URL中的 SFODataSet 不正确.当应用运行时,正试图从.../odata/v2/SFODataSet/$ metadata获取元数据,这就是为什么找不到它的原因. 该SFODataSet来自SFSF元数据:

          Clearly, that SFODataSet in the URL is not correct. When the app runs, it's tring to get the metadata from .../odata/v2/SFODataSet/$metadata, and that's why it's not finding it. That SFODataSet is coming from the SFSF metadata:

          <Schema Namespace="SFODataSet" xmlns="http://schemas.microsoft.com/ado/2008/09/edm" xmlns:sf="http://www.successfactors.com/edm/sf" xmlns:sap="http://www.sap.com/Protocols/SAPData">
                <EntityContainer Name="EntityContainer" m:IsDefaultEntityContainer="true">
                  <EntitySet Name="JobOfferTemplate_Standard_Offer_Details" EntityType="SFOData.JobOfferTemplate_Standard_Offer_Details" sap:label="JobOfferTemplate_Standard_Offer_Details" sap:creatable="false" sap:updatable="false" sap:upsertable="false" sap:deletable="false">
                    <Documentation>
                      <Summary>Job Requisition Template</Summary>
                      <LongDescription>These entities represent the job requisition template as defined in provisioning.</LongDescription>
                      <sap:tagcollection>
                        <sap:tag>Recruiting (RCM)</sap:tag>
                        <sap:tag>RCM - Job Requisition</sap:tag>
                      </sap:tagcollection>
                    </Documentation>
                  </EntitySet>
                  <EntitySet Name="JobRequisitionLocale" EntityType="SFOData.JobRequisitionLocale" sap:label="JobRequisitionLocale" sap:creatable="false" sap:updatable="false" sap:upsertable="false" sap:deletable="false">
                    <Documentation>
          ...
          

          我找不到解决办法.您能帮我在这里找到问题吗?

          I can't find the way for this to work. Can you help me find the issue here?

          我正在使用:

          • Apache Maven 3.6.2
          • SAP Cloud SDK 3.13.0

          SFSF元数据文件位于 https://api.sap.com/中 我为此应用程序使用的是SFSF-Job Requisition,可在此处获取: https://api.sap.com/api/RCMJobRequisition/overview

          SFSF metadata files are available in https://api.sap.com/ The one I'm using for this app is for SFSF - Job Requisition, available here: https://api.sap.com/api/RCMJobRequisition/overview

          您可以从那里下载EDMX规范.这些是模拟" API,未连接到实际的SFSF实例,但是问题是相同的.

          From there, you can download the EDMX specification. These are "mock" API's, not connected to a real SFSF instance, but the problem is the same.

          为此,我主要关注两个博客:

          To do this I'm following two blogs mainly:

          • https://blogs.sap.com/2018/04/30/deep-dive-10-with-sap-s4hana-cloud-sdk-generating-java-vdm-for-s4hana-custom-odata-service/
          • https://blogs.sap.com/2019/05/06/create-an-application-with-sap-cloud-sdk-to-integrate-with-sap-successfactors/

          此外,我删除了最后一部分,因为我将打开一个单独的问题: SFSF OData调用:无法将响应转换为ODataFeed:发生了'EdmSimpleTypeException'

          Also, I removed tha last part as I will open a separate question: SFSF OData call: Failed to convert response into ODataFeed: An 'EdmSimpleTypeException' occurred

          谢谢

          kepair

          推荐答案

          我将首先给出部分答案,并在以后根据需要编辑更多信息.

          I will start of with a partial answer and edit in more information later if needed.

          关于网址:

          您观察到的行为是故意的.请求的完整URL将按以下方式组装:目标URL +服务路径+服务名称+实体+'?' +查询参数.因此,在您的情况下,可能是:

          The behaviour you observe is intentional. The full URL of a request will be assembled as follows: Destination URL + service path + service name + entity + '?' + query parameters. So in your case that might be:

          https://my.host.domain/odata/v2/JobRequisitions/MyEntity
          Destination: https://my.host.domain
          Service Path: /odata/v2
          Service name: JobRequisitions
          Entity: MyEntity
          

          生成器从service path + service name汇编默认的基本路径.实际上,service name将从EDMX的名称空间中提取.这就是为什么以这种方式生成服务URL的原因.

          The generator assembles the default base path from service path + service name. The service name will actually be pulled from the namespace of the EDMX. That is why the URL of your service is being generated the way it is.

          原因很简单:一个人可能想同时为多个服务生成一个VDM.除了服务名称本身之外,所有这些服务都在同一终结点下公开.为了生成具有一种配置的所有VDM,我们可以在生成器中指定服务路径",然后生成器从EDXM本身提取服务名称.

          The reason for this is simple: One might want to generate a VDM for multiple services at the same time. All of these services are exposed under the same endpoint except for the service name itself. In order to generate all the VDMs with one configuration we can specify the "service path" in the generator and the generator pulls the service name from the EDXM itself.

          所以这意味着您覆盖生成的基本路径的方法应该起作用:

          So that means that your approach of overwriting the generated base path should work:

          final List<JobRequisition> jobReqs = new DefaultRCMJobRequisitionService()
                          .withServicePath("odata/v2/JobRequisition")
                          .getAllJobRequisition()
                          .execute(destination);
          

          问题末尾的错误消息对我来说有点像解析问题.但是,为了进一步解决这一问题,我们需要完整的堆栈跟踪和HTTP日志输出.此外,我们只有在有权访问元数据的情况下,才能重现该问题.您提供的链接需要通过用户名/密码进行授权.

          The error message at the very end of your question looks a bit like a problem with parsing to me. But in order to tackle that one further we would need the full stack trace and the HTTP log output. Also, we can only reproduce the problem if we have access to the metadata. The link you provided requires authorization through username/password.

          由于上面的问题已经很全面了,如果确实是一个独立的问题,我建议您将这两个问题分开并创建一个新的问题.这也将使这两个问题与其他问题更加相关.

          Since your question above is already quite comprehensive I would recommend that you separate these two problems and create a new question, if this really turns out to be an independent problem. This will also make both questions more relevant for others.

          这篇关于在SAP Cloud SDK中使用Java生成SFSF的VDM:生成的URI错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆