[英]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:
我正在按照以下步骤操作:
mvn archetype:generate "-DarchetypeGroupId=com.sap.cloud.sdk.archetypes" "-DarchetypeArtifactId=scp-cf-tomee" "-DarchetypeVersion=RELEASE"
<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>
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>
[main] INFO com.sap.cloud.sdk.datamodel.odata.generator.DataModelGenerator - Default base path: /odata/v2/
[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:我正在使用:
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.