Skip to Content
Technical Articles
Author's profile photo Yohei Fukuhara

SAP Cloud SDK for JavaのVDM Generatorを使う

SAP Cloud SDK for JavaのVDM Genaratorを使ってVDMを作成し、オンプレS/4HANA ODataを呼び出します。

今回のプログラムはGitHubに置いています(今回以外の内容もあるので注意)。

開発環境

以下の環境で実行しています。

  • OS: Windows10 64-bit
  • openJDK: 1.8.0_242
  • Chocolatey: 0.10.15
  • maven: 3.6.3
  • IDE: IntelliJ IDEA Community Edition 2019.3.3
  • CF cli: 6.37.0+a40009753.2018-05-25
  • SAP Cloud SDK for Java: 3.15.1

手順

0. 前提

1. メタデータ保存

1.1. ディレクトリ作成

<project-root>/applicationの下に”edmx”というディレクトリを作成します。

1.2. メタデータダウンロード

今回はS/4 HANAのODataを呼び出すので、S/4 HANAにログインしてメタデータを照会します。「Generate .edmx and/or .xml file for Fiori App developed using SAP Web IDE」を参考にしました。

銀行系は軽くて手頃かと思い”/sap/opu/odata/sap/FCLM_BM_SRV/”を使っています。http://<host>:<port>/sap/opu/odata/sap/FCLM_BM_SRV/$metadata?sap-language=E でメタデータをダウンロード。”Bank.xml”という名前で保存しています。日本語ではなく英語でログインしましてダウンロードしないと後続でエラーになりました。

2. IDEにPluginインストール

IntelliJ IDEAのPluginとして“IntelliJ Lombok plugin”をインストールします。IntelliJ IDEAのメニュー File -> Settings を選択し、Pluginのメニューから上記を検索してインストール。

これがないと、いろいろなエラーが起きます。

3. POM.xml調整

<project-root>/application/POM.xmlのdependenciesパス配下に以下を追加します。

        <!-- for vdm generator -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>

また、同じファイルの build -> plugins パス配下に以下を追加します。バージョンはリンク先のMaven Repositoryを見て合わせてください。

※V4の場合はData Model OData V4 Services Generatorも必要かも。

            <plugin>
                <groupId>com.sap.cloud.sdk.datamodel</groupId>
                <artifactId>odata-generator-maven-plugin</artifactId>
                <version>3.15.1</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>
                            <deleteOutputDirectory>true</deleteOutputDirectory>
                            <packageName>com.vdm</packageName>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <version>3.1.0</version>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>add-source</goal>
                        </goals>
                        <configuration>
                            <sources>
                                <source>${project.build.directory}/vdm</source>
                            </sources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

4. VDMクラス生成

パッケージ生成します。

# from application directory
mvn clean package

するとvdmクラスが生成されています(IntelliJ IDEAから参照)。

そして、ディレクトリをソースとして認識させます。

5. サーブレット作成

<project-root>/application/src/main/java/com/sap/cloud/sdkにGetBankServlet のJava Classを作成します。

package com.sap.cloud.sdk;

import com.google.gson.Gson;
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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;

// generated by SAP Cloud SDK VDM generator
import com.vdm.namespaces.bank.Bank;
import com.vdm.services.DefaultBankService;

@WebServlet("/bank")
public class GetBankServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    private static final Logger logger = LoggerFactory.getLogger(GetBankServlet.class);
    private static final ErpHttpDestination destination =
            DestinationAccessor.getDestination("Erp1809")
                    .asHttp().decorate(DefaultErpHttpDestination::new);

    @Override
    protected void doGet(final HttpServletRequest request, final HttpServletResponse response)
            throws IOException {

        logger.info("Start get method: " + request.getRequestURI());

        try{
            final List<Bank> banks =
                    new DefaultBankService()
                            .getAllBank()
                            .select(Bank.BANK_KEY, Bank.BANK_NAME)
                            .filter(Bank.BANK_COUNTRY.eq("JP"))
                            .top(5)
                            .execute(destination);
            logger.info(new Gson().toJson(banks));
            response.setContentType("application/json");
            response.setCharacterEncoding("UTF-8");  //日本語用
            response.getWriter().write(new Gson().toJson(banks));

        } catch (final ODataException e){
            logger.error(e.getMessage(), e);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            response.getWriter().write(e.getMessage());
        }
    }
}

6. ローカル実行

あとは今までと変わらず、ローカルで実行します。

ローカルで実行する場合は環境変数でDestinationの設定をしておいてください。

set destinations=[{name: "Erp1809", url: "http://<host>:<port>", username: "xxx", password: "xxx", sap-language: "ja"}]

で、tomee 起動します。

mvn clean package && mvn tomee:run

ブラウザで http://localhost:8080/bankを開いてJSONで以下が出力されました。

[{"BankInternalId":"0000000","BankName":"銀行 冨田"},{"BankInternalId":"0000001","BankName":"bank ale3 test"},{"BankInternalId":"0000777","BankName":"ダミー銀行"},{"BankInternalId":"0001001","BankName":"ミズホ"},{"BankInternalId":"0001026","BankName":"ミズホ"}]

CFにデプロイしても同じなので割愛します。

SAP Cloud SDK for Java関連記事

Assigned Tags

      3 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo 司 伊丹
      司 伊丹

      sap-cloud-sdkを利用してS/4HANA ODataの取得を試みています。

      下記のようなリクエストのサービスではご紹介いただいた方法で、VDMクラスを生成してoDataを取得することができました。

      https://<hostname>/sap/odata/sap/<servicename>/<entity>

       

      一方、下記のようなリクエストのサービスのoData取得で取得方法がわかりませんでした。

      https://<hostname>/sap/odata/sap/<servicename>/<entity>(startDate=datetime'2022-01-01T00:00:00',endDate=datetime'2022-06-10T00:00:00')/Set

      この場合でもmetadataからVDMクラスを生成することはできました。

      しかし、VDMクラスが備えているメソッドの利用方法がわかりません。

      本Blogの例では、VDMクラスはgetAll<entity名>のようなメソッドを備えており、これを利用することでoDataを取得していましたが、これに相当するメソッドがありませんでした。

       

      おそらくNavigation Propertyが入ったリクエストのため、リクエストの表現方法が異なるためだと思います。

      Navigation Propertyや必須のパラメータが入ったリクエストの取得方法の参考ページなどあれば教えていただけますでしょうか。

      Author's profile photo Yohei Fukuhara
      Yohei Fukuhara
      Blog Post Author

      結論から言うと、私にわかりません。

      以前、同様のことを調べて諦めた記憶があります。2年前のことなので、記憶が曖昧ですが、当時はできないと結論づけました(調査時間が足りなかったか、技術的にサポートしていないパターンかのどちらかです)。ただ、2年間ほど調べていないので、現在はできるかもしれないです。

      Author's profile photo 司 伊丹
      司 伊丹

      ご回答ありがとうございます。

      承知しました。