Claude Media
Claude CodeでABAP Cloud移行のATC指摘を仕分ける — 置換APIとラッパーの分け方

Claude CodeでABAP Cloud移行のATC指摘を仕分ける — 置換APIとラッパーの分け方

ATCのクリーンコア指摘を、公開リポジトリのJSONで置換先ありと要ラッパーに仕分ける手順です。照合はスクリプトに任せ、Claude Codeには判断が要る箱だけを渡します。

ABAP Cloudへの移行で最初に手が止まるのは、ATC(ABAP Test Cockpit)が吐く数百〜数千件の指摘です。どれも「未公開のAPIを使っている」という同じ文言なのに、直し方は一件ずつ違います。名前を差し替えれば済むものもあれば、呼び出し方ごと書き換えるものも、ラッパーを挟むしかないものもあります。

この記事では、指摘の一覧を4つの箱に仕分ける手順を扱います。照合に使うのは、SAPが公開しているCloudification Repository(リリース済みAPIと後継の対応表)のJSONです。Claude Codeには照合スクリプトを書かせ、判断が要る箱だけを claude -p で読ませます。

ATC指摘は4つの箱に分けると進めやすい

指摘を直す順番は、置換先がどれだけはっきりしているかで決まります。次の4つに分けると、着手の順番が見えます。

仕分け

指摘を分ける4つの箱

  • A: 公開済み

    対象がリリース済みAPIとして載っている箱です。本来は指摘が出ないはずなので、ATC側の参照ファイルと手元のJSONの版がずれている可能性があります。まず参照ファイルを揃えます。

  • B: 後継あり

    未公開または非推奨で、後継オブジェクトがJSONに載っている箱です。名前の置換で済むか、呼び出し方の書き換えが要るかをここで見分けます。

  • C: 要ラッパー

    後継は無いが、クラシックAPIとして分類されている箱です。ABAP Cloudからは直接呼べないので、公開済みの層でラッパーを作って橋渡しします。

  • D: 手作業

    どちらのJSONにも載っていない箱です。自作オブジェクトか、対象リリースが違う可能性があり、人が読んで決めます。

Bから先に片付けるのが現実的です。後継が決まっているので迷いが少なく、件数も減らせます。Cはラッパーの設計が要り、Dは調査が要るので後回しになります。

仕分けの材料になる公開リポジトリのJSON

照合の元になるのは、SAPが公開している abap-atc-cr-cv-s4hc リポジトリです。READMEによると、リリース済みAPIの一覧と、未公開オブジェクトの後継情報が1つのJSONにまとまっています。このJSONは、ATCチェック「Usage of Released APIs (Cloudification Repository)」の内容として使われます。

使うファイルは2つです。

ファイル中身仕分けでの役割
objectReleaseInfo_PCELatest.json中身公開状態と後継仕分けでの役割AとBの判定
objectClassifications_SAP.json中身クラシックAPIの分類仕分けでの役割Cの判定

READMEでは、SAP Cloud ERP Private向けのチェックにこのPCELatestを指定する例が示されています。SAP Cloud ERP向けは objectReleaseInfoLatest.json です。対象製品とリリースに合うファイルを選びます。選び違えると、AやDに誤って振り分けられます。

JSONの中を見ると、仕分けに使える項目が揃っています。PCELatestを数えると45,148件で、state の内訳は次のとおりです。

数字

PCELatestのstate内訳

  • released

    43,611

    公開済み

  • notToBeReleased

    619

    非公開扱い

  • notToBeReleasedStable

    608

    READMEに説明なし

  • deprecated

    310

    非推奨

取得したファイルの集計です。ファイルは更新されるため件数は目安です。

後継は successorClassification で表されます。値は oneObject(後継が1つ)、multipleObjects(複数)、concept(オブジェクトでなく考え方で示される)の3種類です。concept の後継は successorConceptName に文字列で入り、例えば「Automatic Job Restart in BTP」のような名前が見つかります。

クラシックAPI側の objectClassifications_SAP.json は8,601件で、classicAPI が8,128件、noAPI が473件です。labels には remote-enabled(3,960件)と transactional-consistent(2,673件)があります。種別は関数モジュール(FUNC)が5,251件と最多です。

JSONをそのままClaudeに読ませない

PCELatestは約12MBあります。READMEは、LLM向けの圧縮形式TOONでも約300万トークン(3,659,440から2,989,644へ)と書いています。会話に貼って「この指摘を分類して」と頼む使い方は成り立ちません。

照合は決まった手順の機械作業なので、スクリプトに任せます。Claude Codeの役目は、そのスクリプトを書くことと、スクリプトが振り分けられなかった箱を読むことです。

照合スクリプトを書かせて動かす

ATCの指摘は、まずCSVにして渡します。列は object_type、object_name、message の3つに絞ります。ATCのエクスポート形式そのものではなく、この記事で決めた入力形式です。実際の出力から列を取り出す部分は、環境に合わせて直します。

作業ディレクトリのCLAUDE.mdに、守ってほしい前提を書いておきます。

# ATC指摘の仕分け
- 照合の元データは objectReleaseInfo_PCELatest.json と objectClassifications_SAP.json。
  どちらも数MBあるので、全文を読まず python3 か jq で引く
- 仕分けは classify.py の出力(A/B/C/D)を正とし、手で区分を書き換えない
- 後継が BDEF の指摘は、名前の置換ではなく呼び出し方の書き換えとして扱う

JSONはcurlで取得します。取得はこちらで済ませ、Claude Codeからの外部通信は止めておきます。

curl -sLO https://raw.githubusercontent.com/SAP/abap-atc-cr-cv-s4hc/main/src/objectReleaseInfo_PCELatest.json
curl -sLO https://raw.githubusercontent.com/SAP/abap-atc-cr-cv-s4hc/main/src/objectClassifications_SAP.json

権限は .claude/settings.json で絞ります。読み取りと、仕分けスクリプトの実行だけを許可します。

{
  "permissions": {
    "allow": ["Read", "Bash(python3 classify.py *)"],
    "deny": ["Bash(curl *)"]
  }
}

広いdenyルールは、より狭いallowルールがあっても優先されます。Bash(curl *) をdenyに置くと、Claudeが指摘対象のソースを調べている最中にcurlで外部から取得させることを止められます。権限の書き方は、allowedToolsとdisallowedToolsの記事にまとめています。

照合スクリプトは次の形です。Claude Codeに「この仕様で書いて」と頼む叩き台として使えます。

import csv, json, sys
 
rel = {(i["objectType"], i["objectKey"]): i
       for i in json.load(open("objectReleaseInfo_PCELatest.json"))["objectReleaseInfo"]}
cls = {(i["objectType"], i["objectKey"]): i
       for i in json.load(open("objectClassifications_SAP.json"))["objectClassifications"]}
 
rows = []
for r in csv.DictReader(open(sys.argv[1])):
    k = (r["object_type"], r["object_name"])
    a, c = rel.get(k), cls.get(k)
    if a and a["state"] == "released":
        bucket, hint = "A released", ""
    elif a and a.get("successors"):
        bucket = "B successor"
        hint = ",".join(s["objectKey"] for s in a["successors"][:3])
    elif a and a.get("successorClassification") == "concept":
        bucket, hint = "B concept", a.get("successorConceptName", "")
    elif c and c["state"] == "classicAPI":
        bucket = "C wrapper"
        hint = "+".join(c.get("labels", [])) or "no-label"
    else:
        bucket, hint = "D manual", ""
    rows.append({**r, "bucket": bucket, "hint": hint})
json.dump(rows, sys.stdout, ensure_ascii=False, indent=1)

判定の順序が肝心です。先に「公開済みか」を見て、次に「後継があるか」、最後に「クラシックAPIか」を見ます。クラシックAPIの分類は、後継が見つからなかったオブジェクトにだけ当てます。

次のような7件で動かしました。

python3 classify.py findings.csv | jq -r '.[] | [.object_name,.bucket,.hint] | @tsv'

結果は次のとおりです。

オブジェクト箱ヒント
CL_BCS箱BヒントCL_BCS_MAIL_MESSAGE
MARA箱BヒントI_PRODUCT、I_PRODUCTPROCUREMENT、I_PRODUCTQM(ほか)
BAPI_PO_CREATE1箱Cヒントremote-enabledとtransactional-consistent
BAPI_SALESORDER_CREATEFROMDAT2箱BヒントI_SALESORDERTP
CL_ABAP_CONTEXT_INFO箱Aヒントなし
CL_SALV_TABLE箱Cヒントラベルなし
ZZ_UNKNOWN_TAB箱Dヒントなし

後継の数が箱の中身を分けています。CL_BCS の後継は1つで、クラス名の差し替えに近い作業です。MARA は5つのCDSビューに分かれ、どの項目を読むかで使うビューが変わります。1対1の置換ではありません。

BAPI_SALESORDER_CREATEFROMDAT2 の後継は I_SALESORDERTP で、種別はBDEF(ビヘイビア定義)です。関数モジュールの呼び出しが、ビヘイビア定義を通すアクセスに変わります。CLAUDE.mdに書いた「BDEFは書き換え扱い」は、この種類の指摘を名前の置換に回さないための一行です。

判断が要る箱だけを claude -p に渡す

CとDは、呼び出し側のソースを読まないと方針が決まりません。この2つを抜き出して、非対話モードで読ませます。

python3 classify.py findings.csv > triage.json
jq '[.[] | select(.bucket | startswith("C") or startswith("D"))]' triage.json > needs-review.json
 
claude -p "needs-review.json の各オブジェクトについて、src 配下の呼び出し箇所を探し、\
ラッパーを作るか、呼び出しを書き換えるか、人が調べるかを提案して" \
  --allowedTools "Read,Grep,Glob" \
  --output-format json \
  --json-schema '{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string"},"callSites":{"type":"array","items":{"type":"string"}},"proposal":{"type":"string","enum":["wrapper","rewrite","manual"]},"reason":{"type":"string"}},"required":["object","proposal","reason"]}}},"required":["items"]}' \
  | jq '.structured_output.items[]'

ここで使っているのは、非対話モードの標準的な機能です。

  • -p で非対話実行にする
  • --allowedTools で読み取り系のツールだけを事前承認する
  • --json-schema で出力の形を固定する。結果は structured_output に入る

--allowedTools に書き込み系を入れていないので、この実行でソースは変わりません。分類の提案を読んでから、手を入れる段階に進みます。

出力が有効な構造化出力にならなかった場合、structured_output フィールド自体が付きません。後続の jq に流す前に、フィールドがあるかを確かめます。

CIのように、ホスト環境のフックやCLAUDE.mdを読み込ませたくない場面では --bare を付けます。ただし --bare はサブスクリプションのログインを使わないため、ANTHROPIC_API_KEY を環境に設定しておく必要があります。この仕分けでは手元のCLAUDE.mdを読ませたいので、付けない構成です。claude -p 全般の扱いはclaude -p の解説にあります。

標準入力にログを流し込む場合は10MBの上限があります。指摘の一覧が大きいときは、パイプでなくファイルを渡します。上限の挙動はclaude -p の10MB上限の記事で扱っています。

置換APIで済むものとラッパーが要るものの境目

Bの中でも、作業の重さはさまざまです。後継の種類で見ておくと、見積もりが立てやすくなります。

後継の形作業の中身
oneObjectで同じ種別作業の中身名前の差し替えと、パラメータの見直し
oneObjectで種別が変わる作業の中身呼び出し方の書き換え(例: 関数モジュールからBDEFへ)
multipleObjects作業の中身使う項目から後継を選ぶ設計作業
concept作業の中身オブジェクトでなく仕組みの置き換え

Cは、READMEが「クラシックAPIをラッパーとして使い、ABAP Cloudへ橋渡しする」と案内している領域です。READMEは、フィルタをclassic APIとラベル transactional-consistent に絞った一覧を紹介しています。ラッパーの生成には、SAPのサンプルリポジトリ tier2-rfc-proxy が使えます。

ラベルは優先順位の手がかりになります。transactional-consistent が付くクラシックAPIは、READMEの「Related projects」でラッパーの候補として絞り込み条件に挙がっています。BAPI_PO_CREATE1 のように両方のラベルが付いたものから着手すると、橋渡しの設計を最初に固められます。一方、CL_SALV_TABLE のようにラベルが無いクラシックAPIは、JSONからは分かる情報が少ない状態です。ラッパーにするか、呼び出しを別の仕組みへ置き換えるかを、画面側の使い方まで見て決めます。

仕分けがずれるときの確認先

結果が想定とずれたときは、次の順に当たります。

  1. Aが多い: ATCが参照しているJSONの版と、手元のJSONが違うことを疑います。READMEは、ATCチェックの属性にJSONのURLを入れる手順を示しています。URLが古い版のままになっていないかを見ます
  2. Dが多い: 自作の Z 名前空間オブジェクトはDに入ります。自作オブジェクトを公開扱いにする仕組みはREADMEの要件にあり、SAPノート3507814が挙がっています
  3. ATCが外部のJSONを取れない: READMEはSAPノート3582797で、チェック「Usage of APIs」がSSL handshake failedになる場合を案内しています。S/4システムからgitへの接続を成り立たせる設定が前提です
  4. チェック名が見つからない: JSONの中に、旧チェックバリアントから新しいものへの後継が載っています。例えば SAP_CP_READINESS の後継は ABAP_CLOUD_READINESS です

READMEには、ATCチェックを使うための前提ノートも並んでいます。ノート3284711、3377462、3507814が挙がり、クリーンコア向けでは3449860や3565942が登場します。仕分けの前に、システム側でこれらが当たっているかをBasis担当に確かめておくと、手戻りが減ります。

まとめ

ATC指摘の仕分けは、照合と判断を分けると進みます。公開リポジトリのJSONとの突き合わせは、スクリプトで決定的に行います。Claude Codeには、そのスクリプトを書かせることと、CとDの呼び出し箇所を読ませることを任せます。

最初の一手は、Bのうち後継が1つで種別も同じものです。ここを片付けるだけで指摘の山が減り、残りがCとDに絞れます。SAP連携を別の側面から見るなら、Claude SAP連携ガイドも参考になります。

参照した一次ソース

この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。

  1. github.com/SAP/abap-atc-cr-cv-s4hc
  2. code.claude.com/docs/en/headless
  3. code.claude.com/docs/en/permissions
この記事を共有:XはてブLinkedIn