简体   繁体   English

在 SAP Cloud SDK 中使用 Java 为 SFSF 生成 VDM:生成的 URI 是错误的

[英]Generate VDM for SFSF using Java in SAP Cloud SDK: Generated URI is wrong

I'm trying to build an app that reads info from SFSF.我正在尝试构建一个从 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.为此,我将虚拟数据模型生成器工具(maven 插件)与 SFSF OData 元数据一起使用,以便能够访问系统。 I'm following these steps:我正在按照以下步骤操作:

  • Get a project via archetype (with powershell):通过原型获取项目(使用 powershell):
mvn archetype:generate "-DarchetypeGroupId=com.sap.cloud.sdk.archetypes" "-DarchetypeArtifactId=scp-cf-tomee" "-DarchetypeVersion=RELEASE"
  • Add the following to the application\\pom.xml In dependencies:将以下内容添加到 application\\pom.xml 中的依赖项中:
<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
</dependency>

In plugins:在插件中:

<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>
  • Get the OData metadata file from https://apisalesdemo2.successfactors.eu/odata/v2/JobRequisition/$metadata and place it in ./application/edmxhttps://apisalesdemo2.successfactors.eu/odata/v2/JobRequisition/$metadata获取 OData 元数据文件并将其放入 ./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)创建一个目标服务 (my-destination) 并在那里添加一个指向我的 SFSF 实例的目标,使用基本身份验证(使用 user@companyId,连接为 200:OK)
  • Add the destination service in the manifest.yml在 manifest.yml 中添加目标服务
  • Create a java class to call the destination and get the data:创建一个java类来调用目的地并获取数据:
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

and:和:

cf push

Everything works well, the hello world servlet works, but when I try to access /req, I get a: Unable to execute metadata request.一切正常,hello world servlet 正常工作,但是当我尝试访问 /req 时,我得到一个:无法执行元数据请求。

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.但是,我可以看到该应用程序正在访问 SFSF,因为如果我使用服务的基本路径(在 pom.xml 中),我会收到来自 SFSF 的 404。

Checking everything, I see this when the VDM generator is running: 1. This is the base path I'm giving in the pom:检查所有内容,我在 VDM 生成器运行时看到了这一点: 1. 这是我在 pom 中给出的基本路径:

<defaultBasePath>/odata/v2</defaultBasePath>
  1. I can see the generator picking that path correctly:我可以看到生成器正确选择了该路径:
[main] INFO com.sap.cloud.sdk.datamodel.odata.generator.DataModelGenerator -   Default base path:              /odata/v2/
  1. But this is what the generator processes:但这是生成器处理的:
[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

Clearly, that SFODataSet in the URL is not correct.显然,URL 中的SFODataSet不正确。 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.当应用程序运行时,它试图从 .../odata/v2/SFODataSet/$metadata 获取元数据,这就是它找不到它的原因。 That SFODataSet is coming from the SFSF metadata:该 SFODataSet 来自 SFSF 元数据:

<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?你能帮我在这里找到问题吗?

I'm using:我正在使用:

  • Apache Maven 3.6.2 Apache Maven 3.6.2
  • SAP Cloud SDK 3.13.0 SAP 云 SDK 3.13.0

Edit: 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编辑:SFSF 元数据文件可在https://api.sap.com/中获得 我用于此应用程序的元数据文件用于 SFSF - Job Requisition,可在此处获得: https : //api.sap.com/api/RCMJobRequisition /概述

From there, you can download the EDMX specification.从那里,您可以下载 EDMX 规范。 These are "mock" API's, not connected to a real SFSF instance, but the problem is the same.这些是“模拟”API,未连接到真正的 SFSF 实例,但问题是相同的。

To do this I'm following two blogs mainly:为此,我主要关注两个博客:

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此外,我删除了最后一部分,因为我将打开一个单独的问题: SFSF OData 调用:无法将响应转换为 ODataFeed:发生“EdmSimpleTypeException”

Thanks,谢谢,

kepair凯佩尔

I will start of with a partial answer and edit in more information later if needed.我将从部分答案开始,然后根据需要编辑更多信息。

Regarding the 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 + '?'请求的完整 URL 将按如下方式组装:目标 URL + 服务路径 + 服务名称 + 实体 + '?' + 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

The generator assembles the default base path from service path + service name .生成器从service path + service name组装默认基本路径。 The service name will actually be pulled from the namespace of the EDMX. service name实际上将从 EDMX 的命名空间中提取。 That is why the URL of your service is being generated the way it is.这就是为什么您的服务的 URL 是按原样生成的。

The reason for this is simple: One might want to generate a VDM for multiple services at the same time.原因很简单:人们可能希望同时为多个服务生成一个 VDM。 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.为了使用一种配置生成所有 VDM,我们可以在生成器中指定“服务路径”,生成器从 EDXM 本身提取服务名称。

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);

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.但是为了进一步解决这个问题,我们需要完整的堆栈跟踪和 HTTP 日志输出。 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.这也将使这两个问题与其他人更相关。

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

相关问题 如何使用 SAP Cloud SDK 3.2.0 在 Java 中检索目标? - How to retrieve a destination in Java with SAP Cloud SDK 3.2.0? 在Java EE中为SAP Cloud Platform使用目标 - Using destinations in Java EE for SAP Cloud Platform 如何使用gcloud或Google Cloud Java SDK生成oauth令牌,客户端ID和密码 - How to generate oauth token, client id and secret using gcloud or Google Cloud Java SDK SAP Cloud SDK (Java) 在 SuccessFactors 元数据加载时引发命名错误异常 - SAP Cloud SDK (Java) throws naming error exception on SuccessFactors metadata load SAP Cloud SDK OData V4 支持 - SAP Cloud SDK OData V4 Support 使用 SAP Cloud SDK 版本 3.2.0 向 OData 服务发送 POST 请求 - Send POST request to OData service using SAP Cloud SDK version 3.2.0 使用 SAP Cloud SDK 3.2.0 版向 OData 服务发送 POST 请求时如何避免 DestinationAccessException - How to avoid a DestinationAccessException when sending a POST request to an OData service using SAP Cloud SDK version 3.2.0 使用参数$ filter和$ expand与VDM生成的类 - Use parameters $filter and $expand with VDM generated classes SAP JCO使用Java在SAP中创建记录 - SAP JCO creating a record in SAP using java 如何修复应用程序启动期间 SAP Cloud SDK 抛出的 DestinationAccessException - How to fix a DestinationAccessException thrown by the SAP Cloud SDK during application startup
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM