Сгенерируйте VDM для SFSF, используя Java в SAP Cloud SDK: сгенерированный URI неверен - PullRequest
2 голосов
/ 24 февраля 2020

Я пытаюсь создать приложение, которое читает информацию из SFSF. Для этого я использую инструмент генератора моделей виртуальных данных (плагин maven) с метаданными SFSF OData, чтобы иметь доступ к системе. Я выполняю следующие действия:

  • Получить проект с помощью архетипа (с powershell):
mvn archetype:generate "-DarchetypeGroupId=com.sap.cloud.sdk.archetypes" "-DarchetypeArtifactId=scp-cf-tomee" "-DarchetypeVersion=RELEASE"
  • Добавьте следующее в приложение \ pom. xml В зависимостях:
<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>
  • Получить файл метаданных OData из https://apisalesdemo2.successfactors.eu/odata/v2/JobRequisition/ $ metadata и поместите его в ./application/edmx
  • Создайте службу назначения (my-destination) и добавьте туда назначение, указывающее на мой экземпляр SFSF с basi c auth (с user@companyId, соединение 200 : OK)
  • Добавить службу получателя в manifest.yml
  • Создать класс 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());
        }
    }
}

Со всем этим (я думаю, что я ничего не пропускаю), я делаю:

mvn clean install

и:

cf push

Все работает хорошо, сервлет hello world работает, но когда Я пытаюсь получить доступ к / req, я получаю: Невозможно выполнить запрос метаданных.

Однако я вижу, что приложение запускает SFSF, потому что, если я играю с базовый путь службы (в pom. xml) Я получаю 404 из SFSF.

Проверяя все, я вижу это, когда работает генератор VDM: 1. Это базовый путь I ' м дает в пом:

<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

Очевидно, что SFODataSet в URL-адресе неверен. Когда приложение запускается, оно пытается получить метаданные из ... / odata / v2 / SFODataSet / $ метаданных, и поэтому не может их найти. Этот 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>
...

Я не могу найти способ, чтобы это сработало. Можете ли вы помочь мне найти проблему здесь?

Я использую:

  • Apache Maven 3.6.2
  • SAP Cloud SDK 3.13.0

Редактировать: файлы метаданных SFSF доступны в https://api.sap.com/, который я использую для этого приложения, предназначен для SFSF - Заявка на работу, доступна здесь: https://api.sap.com/api/RCMJobRequisition/overview

Оттуда вы можете скачать спецификацию EDMX. Это «фиктивные» API, не связанные с реальным экземпляром SFSF, но проблема та же.

Для этого я в основном слежу за двумя блогами:

Кроме того, я удалил последнюю часть, так как открою отдельный вопрос: SFSF Вызов OData: не удалось преобразовать ответ в ODataFeed: возникло исключение EdmSimpleTypeException

Спасибо,

kepair

1 Ответ

3 голосов
/ 24 февраля 2020

Я начну с частичного ответа и позже при необходимости отредактирую дополнительную информацию.

Относительно 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. Кроме того, мы можем воспроизвести проблему, только если у нас есть доступ к метаданным. Ссылка, которую вы предоставили, требует авторизации через имя пользователя / пароль.

Поскольку ваш вопрос выше уже достаточно исчерпывающий, я бы порекомендовал разделить эти две проблемы и создать новый вопрос, если это действительно окажется независимой проблемой. , Это также сделает оба вопроса более актуальными для других.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...