タイトルの件、調査がてら書きました。
デプロイ方法
レポジトリ取得
$ git clone https://github.com/yomon8/aws-lambda-hello-sap.git
SAP JCoの準備
動かすにはがSAP JCo必要ですが、リポジトリに含めるのはまずいので除いています。この記事読んでる人ならSユーザ持ってる人多いと思うので、こちらからダウンロードしてください。
必要なのは Linux (for Intel compatible processors)
の 64-bit x86
です。
ダウンロードしたファイルを解凍すると以下のようなファイルが入っているはずです。
$ ls -1 Readme.txt examples javadoc libsapjco3.so sapjco3.jar sapjcomanifest.mf
sapjco3.jar
と libsapjco3.so
を先程Cloneしたリポジトリのlibフォルダに配置します。
$ ls lib/
libsapjco3.so sapjco3.jar
ビルド
Gradleでビルドすると、jarファイルが生成されます。
$ gradle build
$ ls build/libs/aws-lambda-hello-sap.jar
build/libs/aws-lambda-hello-sap.jar
AWS Lambda作成
AWS Management ConsoleからJava8でAWS Lambdaを作成します。特別なロールは不要です。VPC等は適切に設定してください。
jarファイルをアップロードする際にはハンドラに、com.example.hellosap.HelloSAP::handleRequest
と設定します。
テスト用のイベントを作ってみます。
作成したイベントを使ってLambdaを呼び出したところSAPから応答が帰ってきているのがわかります。
SAMでローカルテストとデプロイ
リポジトリのルートにあるtemplate.yaml
を準備しているので、SAPとネットワーク繋がる環境にローカル環境があるなら、ローカル環境でLambdaのテストもできます。
$ echo '{"host":"YOUR ABAP HOST","sysnum":"00","client":"800","user":"DDIC","password":"19920706"}' | sam local invoke --省略-- {"echoText":"Hello SAP","respText":"SAP R/3 Rel. 740 Sysid: SID Date: 20180709 Time: 151017 Logon_Data: 800/DDIC/J"} --省略--
当然、そのままSAMでデプロイも可能です。
$ aws cloudformation package \ --s3-bucket ${S3_STAGING_BUCKET} \ --s3-prefix ${S3_STAGING_KEY} \ --template-file ./template.yaml \ --output-template-file ./packaged.yaml $ aws cloudformation deploy \ --template-file ./packaged.yaml \ --stack-name hello-sap \ --capabilities CAPABILITY_IAM
ポイント
引っかかったりした部分を並べておきます。
最新のライブラリ
AWSのデベロッパーガイド等を見ていたのですが、結構内容古いです。ライブラリもMavenのリポジトリ直接確認した方が良いと思われます。
POJOを利用したデータを受け渡し
JSONでログオンデータを渡してましたが、こちらを参考に実装していま。
例: ハンドラーの入出力に POJO を使用する (Java) - AWS Lambda
Gradleにjarやsoを含める
今回はVisual Studio Code使って作りましたが、libファイルに置いたjarは以下の設定で読み込めるようになります。
dependencies { compile 'com.amazonaws:aws-lambda-java-core:1.2.0' compile files('lib/sapjco3.jar') }
加えて以下の設定をbuild.gradleに入れることで、生成されるjarファイルにsapjco3.jar
と libsapjco3.so
を含められるようになりました。
jar { into('lib') { from 'lib' } from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } }
VPCでは注意が必要
JCoは通信時に内部的にローカルホストの解決をしようとするみたいなのですが、VPCにENIをおろしているとローカルホストの解決が正しくできないので、エラーを吐いてしまっているようです。
例えば下の例で言えば、 `ASHOST=192.168.1.2` を相手に指定しているのに、何故か `hostname 'ip-10-11-180-183' unknown` とかローカルのホストの解決でエラーを吐いてしまいます。
START RequestId: 8e59bdfd-8a2c-11e8-b45a-9577fea6fb56 Version: $LATEST Start192.168.1.229Result:trueip-10-11-180-183: ip-10-11-180-183: Name or service not knowncom.sap.conn.jco.JCoException: (102) JCO_ERROR_COMMUNICATION: Initialization of repository destination failed: Connect to SAP gateway failed Connection parameters: TYPE=A DEST="<Java Rfc client>" ASHOST=192.168.1.2 SYSNR=00 GWHOST=192.168.1.2 PCS=1 LOCATION CPIC (TCP/IP) on local host with Unicode ERROR hostname 'ip-10-11-180-183' unknown TIME Wed Jul 18 01:47:56 2018 RELEASE 721 COMPONENT NI (network interface) VERSION 40 RC -2 MODULE nixxhl.cpp LINE 193 DETAIL NiHLGetNodeAddr: hostname cached as unknown COUNTER 2 END RequestId: 8e59bdfd-8a2c-11e8-b45a-9577fea6fb56 REPORT RequestId: 8e59bdfd-8a2c-11e8-b45a-9577fea6fb56 Duration: 7332.38 ms Billed Duration: 7400 ms Memory Size: 128 MB Max Memory Used: 90 MB
これは、Route53等の内部DNSで名前引きできる環境だとエラー出ずに通信できます。