Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Fukuhara
Advisor
Advisor
SAP Cloud SDK for JavaのVDMを使ってオンプレS/4HANA ODataを呼び出します。

Connect to OData Service on Cloud Foundry Using SAP Cloud SDKの内容を少し変えています。

今回のプログラムは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. 環境変数設定


コマンドプロンプトで一時的な環境変数を設定します。証明書関連が面倒なのでHTTPSでなくHTTPアクセスにしています。クライアントを指定したい場合は"sap-client"を追加すればいいはず(未確認)。
set destinations=[{name: "Erp1809", url: "http://<host>:<port>", username: "xxx", password: "xxx", sap-language: "ja"}]

2. サーブレット作成


<project-root>/application/src/main/java/com/sap/cloud/sdk 以下に"GetCustomerServlet"のJava Classを作成。

URLのパラメータから"name"の値を受け取ってcustomerを部分一致で検索しています。"substringof"を使って部分一致検索をしているのですが、3.15.1時点のSDKでは専用のメソッドはないようです。

このODataはS/4HANA上の"/sap/opu/odata/sap/API_BUSINESS_PARTNER/A_Customer"に対応しています。
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 com.sap.cloud.sdk.s4hana.datamodel.odata.namespaces.businesspartner.Customer;
import com.sap.cloud.sdk.s4hana.datamodel.odata.services.DefaultBusinessPartnerService;
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.ArrayList;
import java.util.List;

@WebServlet("/customer")
public class GetCustomerServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final Logger logger = LoggerFactory.getLogger(GetCustomerServlet.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());
String parameter = request.getParameter("name");
logger.info("Get parameter 'name': " + parameter);

try{
final String searchParameter = "substringof(CustomerName, '" + parameter + "')";

final List<Customer> customers =
new DefaultBusinessPartnerService()
.getAllCustomer()
.withQueryParameter("$filter", searchParameter)
.select(Customer.CUSTOMER, Customer.CUSTOMER_FULL_NAME)
.top(5)
.execute(destination);
logger.info(new Gson().toJson(customers));
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8"); //日本語用
response.getWriter().write(new Gson().toJson(customers));

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

3. ローカル実行


コンパイルしてtomee起動
# from directory application
mvn clean package && mvn tomee:run

以下のurlをブラウザで開く。

http://localhost:8080/customer?name=test

S/4のODataを呼び出し、以下のcustomer検索結果がJSONで表示される。
[{"Customer":"9","CustomerFullName":" test/ test"},{"Customer":"223","CustomerFullName":" HT Test/1234567 TOKYO"},{"Customer":"10000","CustomerFullName":" TEST/111-1111 TEST"},{"Customer":"10001","CustomerFullName":" TEST/111-1111 TEST"},{"Customer":"99993","CustomerFullName":" test/ tokyo"}]

コンソール上には以下のようなログを出します。
09:56:37.566 [http-nio-8080-exec-2] INFO com.sap.cloud.sdk.cloudplatform.connectivity.DestinationAccessor - Creating a new DestinationLoaderChain with EnvVarDestinationLoader as the primary DestinationLoader implementation.
09:56:38.797 [http-nio-8080-exec-2] INFO com.sap.cloud.sdk.cloudplatform.connectivity.DestinationAccessor - Using an instance of ScpCfDestinationLoader as the secondary DestinationLoader implementation.
09:56:40.662 [http-nio-8080-exec-2] INFO com.sap.cloud.sdk.GetCustomerServlet - Start get method: /customer
09:56:40.665 [http-nio-8080-exec-2] INFO com.sap.cloud.sdk.GetCustomerServlet - Get parameter 'name': test
09:56:43.857 [http-nio-8080-exec-2] INFO com.sap.cloud.sdk.GetCustomerServlet - [{"Customer":"9","CustomerFullName":" test/ test"},{"Customer":"223","CustomerFullName":" HT Test/1234567 TOKYO"},{"Customer":"10000","CustomerFullName":" TEST/111-1111 TEST"},{"Customer":"10001","CustomerFullName":" TEST/111-1111 TEST"},{"Customer":"99993","CustomerFullName":" test/ tokyo"}]

 

4. Cloud Foundryへデプロイ


4.1. Destination定義


SAP Cloud Platform Cloud Foundryでサブアカウント(今回はtrial)の Connectivity -> Destinations で以下のように定義(スペース配下にDestinationを作っても大丈夫)。


4.2. Destination インスタンス作成


CF cliでログインして"my-destination"というインスタンスを作成。このDestinationには何も定義しません(4.1でサブアカウント単位でしているから)。
cf login
cf create-service destination lite my-destination

4.3. manifest.yml更新


servicesで「4.2. Destination インスタンス作成」で作成したDestination インスタンスをbindします。また、routesとrandom-routeもついでに変更しました。routeをrandomにして作成し続けるとquotaを超えてエラーになるからです(cli から"cf routes"で既存のrouteを確認できます)。
---
applications:

- name: cloud-sdk-test
memory: 1024M
timeout: 300
routes:
- route: https://<rounte>.cfapps.eu10.hana.ondemand.com
random-route: false
path: application/target/cloud-sdk-test-application.war
buildpacks:
- sap_java_buildpack
env:
TARGET_RUNTIME: tomee7
SET_LOGGING_LEVEL: '{ROOT: INFO, com.sap.cloud.sdk: INFO}'
JBP_CONFIG_SAPJVM_MEMORY_SIZES: 'metaspace:128m..'
services:
# - my-application-logs
# - my-xsuaa
- my-destination
# - my-connectivity

4.4. デプロイ(cf push)


あとはcli で"cf push"でデプロイするだけです。

ブラウザで同じようにhttps://<route><domain>/customer?name=testを開くとローカルと同様の結果が出ます。

SAP Cloud SDK for Java関連記事