我正在尝试构建一个从SFSF读取信息的应用程序。为此,我将虚拟数据模型生成器工具(maven插件)与SFSF OData元数据结合使用,以便能够访问系统。我正在按照以下步骤操作:
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>
在插件中:
<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());
}
}
}
有了这些(我想我什么都没错过),我做到了:
mvn clean install
和:
cf push
一切正常,hello world servlet正常,但是当我尝试访问/ req时,我得到:无法执行元数据请求。
但是,我可以看到该应用正在运行SFSF,因为如果我使用该服务的基本路径(在pom.xml中),则会收到来自SFSF的404。
检查一切,在运行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
显然,URL 中的SFODataSet不正确。当应用程序运行时,正想从... / odata / v2 / SFODataSet / $ 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>
...
我找不到解决办法。您能帮我在这里找到问题吗?
我在用着:
编辑:SFSF元数据文件可在https://api.sap.com/中获得。 我为此应用程序使用的是SFSF-Job Requisition,可在此处获得:https : //api.sap.com/api/RCMJobRequisition /总览
从那里,您可以下载EDMX规范。这些是“模拟” API,未连接到实际的SFSF实例,但问题是相同的。
为此,我主要关注两个博客:
另外,我删除了最后一部分,因为我将打开一个单独的问题: SFSF OData调用:无法将响应转换为ODataFeed:发生了'EdmSimpleTypeException'
谢谢,
一对
我将从部分答案开始,然后在需要时编辑更多信息。
关于URL:
您观察到的行为是故意的。请求的完整URL将按以下方式组装:目标URL +服务路径+服务名称+实体+'?' +查询参数。因此,在您的情况下,可能是:
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的原因。
原因很简单:一个人可能想同时为多个服务生成一个VDM。除了服务名称本身之外,所有这些服务都在同一终结点下公开。为了生成具有一种配置的所有VDM,我们可以在生成器中指定“服务路径”,并且生成器从EDXM本身提取服务名称。
因此,这意味着您覆盖生成的基本路径的方法应该有效:
final List<JobRequisition> jobReqs = new DefaultRCMJobRequisitionService()
.withServicePath("odata/v2/JobRequisition")
.getAllJobRequisition()
.execute(destination);
问题末尾的错误消息对我来说有点像解析问题。但是,为了进一步解决这一问题,我们需要完整的堆栈跟踪和HTTP日志输出。此外,我们只有在可以访问元数据时才能重现该问题。您提供的链接需要通过用户名/密码进行授权。
由于上面的问题已经很全面了,如果确实是一个独立的问题,我建议您将这两个问题分开并创建一个新的问题。这也将使这两个问题与其他问题更加相关。
我在问题的末尾添加了一些参考。您应该能够获得像我在api.sap.com中使用的那样的元数据文件。我有兴趣访问Job Requisition下的一些实体:JobRequisition,JobRequisitionLocale和JobReqScreeningQuestion。
我看了看元数据,答案中描述的内容仍然成立。我概述的VDM的使用方法应该至少在组装的URI方面可以为您提供所需的确切信息。那么,这里仍然存在什么问题呢?
问题在于它构建的URI不存在,调用目标时我需要更改服务路径。我知道这可能是OData提供程序(在这种情况下为SFSF)的问题?
是的,但这不是OData提供程序的“问题”。只是EDMX不遵循这种
namespace == service name
模式而已。服务并非必须这样做。这只是意味着生成器正在使用的这种“启发式”不适用于此处,您必须以编程方式设置基本路径。