進行状況の追跡を始めよう
Trailhead のホーム
Trailhead のホーム

複数組織リリース用の自動メタデータ更新の作成

学習の目的

この単元を完了すると、次のことができるようになります。
  • Apex メタデータ API を使用して組織からメタデータを取得する。
  • Apex メタデータ API を使用してメタデータを更新し、組織にリリースする。

複数組織インストールの一般的な問題を解決する

ここでは、複数組織環境で作業する場合におそらく直面する一般的な問題を解決しましょう。たとえば、事業を展開している国ごとに 1 つずつ、10 個の組織があるとします。組織の更新には管理パッケージを使用しています。取引先のカスタム項目を作成して、全組織のページレイアウトに表示する必要があります。

理想的には、これらの更新を、システム管理者が設定 UI で繰り返し作業せずに行いたいところです。Apex メタデータ API を使用してこのプロセスをどう自動化できるか見てみましょう。

取引先ページレイアウトの既存のメタデータを取得し、新しい項目で更新する Apex コードを確認します。次に、メタデータの更新をリリースする Apex インストール後スクリプトを作成します。各組織の取引先ページレイアウトに項目を追加することなく、組織の管理パッケージをアップグレードするだけです。新しい項目を追加する作業はすべて Apex がバックグラウンドで実行します。

メタデータを取得してカスタム項目をレイアウトに追加する

以下のコード例ではまず、取引先ページレイアウトの現在のメタデータを取得します。次に、メタデータを使用してページレイアウトの取引先情報セクションを見つけます。最後に、カスタム項目のメタデータレイアウト項目を作成し、このセクションのメタデータレイアウト項目のリストに追加します。

  1. [設定] ギア、[開発者コンソール] の順にクリックして開発者コンソールを開きます。
  2. 開発者コンソールで、[File (ファイル)] | [New (新規)] | [Apex Class (Apex クラス)] をクリックします。
  3. このクラスに UpdatePageLayout という名前を付け、[OK] をクリックします。
  4. 既存のコードをすべて削除し、次のコード例をコピーしてその場所に貼り付けます。
public class UpdatePageLayout {
    // Add custom field to page layout
    
    public Metadata.Layout buildLayout() {
        
        // Retrieve Account layout and section 
        List<Metadata.Metadata> layouts = 
            Metadata.Operations.retrieve(Metadata.MetadataType.Layout, 
            new List<String> {'Account-Account Layout'});
        Metadata.Layout layoutMd = (Metadata.Layout) layouts.get(0);
        Metadata.LayoutSection layoutSectionToEdit = null;
        List<Metadata.LayoutSection> layoutSections = layoutMd.layoutSections;
        for (Metadata.LayoutSection section : layoutSections) {
            
            if (section.label == 'Account Information') {
                layoutSectionToEdit = section;
                break;
            }
        }
        
        // Add the field under Account info section in the left column
        List<Metadata.LayoutColumn> layoutColumns = layoutSectionToEdit.layoutColumns;     
        List<Metadata.LayoutItem> layoutItems = layoutColumns.get(0).layoutItems;
        
        // Create a new layout item for the custom field
        Metadata.LayoutItem item = new Metadata.LayoutItem();
        item.behavior = Metadata.UiBehavior.Edit;
        item.field = 'AMAPI__Apex_MD_API_sample_field__c';
        layoutItems.add(item);
        
        return layoutMd;
    }
}

この例では、Apex メタデータ API から Metadata 名前空間にあるクラスとメソッドを使用します。Metadata.Operations.retrieve メソッドは、組織からメタデータを同期的に取得します。取得するメタデータコンポーネント名のリストを指定する必要があります。この場合、取引先ページレイアウトのメタデータを取得します。retrieve メソッドは、一致するコンポーネントデータのリストを返します。これは、Metadata.Metadata から派生したコンポーネントクラスで表されます。

メモ

メモ

このクラスを使用するには、'AMAPI__Apex_MD_API_sample_field__c' を、使用する名前空間と項目名で置き換えます。

Metadata 名前空間のクラスについての詳細は、『Apex 開発者ガイド』を参照してください。

コールバッククラスを指定する

レイアウト項目のメタデータを作成できたので、メタデータを組織にリリースする準備ができました。リリースは非同期のため、キュー内のリリースが完了したら通知を受け取れるようにコールバックを指定します。コールバッククラスは、Metadata.DeployCallback インターフェースを実装している必要があります。

メモ

メモ

コールバックはリリース後に非同期にコールされるため、リリースが完了してからコールバックがコールされるまでの間に少し時間が空く場合があります。

開発者コンソールで、「PostInstallCallback」という名前と次のコードで Apex クラスを作成します。

public class PostInstallCallback implements Metadata.DeployCallback {
  
    public void handleResult(Metadata.DeployResult result,
        Metadata.DeployCallbackContext context) {
        
        if (result.status == Metadata.DeployStatus.Succeeded) {
            // Deployment was successful, take appropriate action.
            System.debug('Deployment Succeeded!');
        } else {
            // Deployment wasn’t successful, take appropriate action.
	    System.debug('Deployment Failed!');
        }
    }
}

リリースコンテナを作成する

Apex Metadata API には、メタデータを現在の組織にリリースするための Metadata.Operations.enqueueDeployment メソッドがあります。このメソッドがコールされると、リリース要求が非同期処理のキューに追加されます。

メモ

メモ

メタデータのリリース時、コンポーネントの作成と更新はできますが、削除はできません。

「DeployMetadata」という名前で次のコードを使用して Apex クラスを作成します。このクラスはリリースコンテナを作成し、そこに新しいレイアウトメタデータを追加します。このコンテナは、リリース完了時にコールされるコールバッククラスをインスタンス化します。その後で Metadata.Operations.enqueueDeployment メソッドをコールして新しいメタデータを組織にリリースします。

public class DeployMetadata {
 
    // Create metadata container 
    public Metadata.DeployContainer constructDeploymentRequest() {
        
        Metadata.DeployContainer container = new Metadata.DeployContainer();
        
        // Add components to container         
        Metadata.Layout layoutMetadata = new UpdatePageLayout().buildLayout();
        container.addMetadata(layoutMetadata);
        return container;
    }
    
    // Deploy metadata
    public void deploy(Metadata.DeployContainer container) {
        // Create callback. 
        PostInstallCallback callback = new PostInstallCallback();
        
        // Deploy the container with the new components. 
        Id asyncResultId = Metadata.Operations.enqueueDeployment(container, callback);
    }
}

メタデータを非同期にリリースする

必要な Apex クラスを作成したので、カスタムメタデータをリリースできます。リリースは、InstallHandler インターフェースを実装する Apex クラスであるインストール後スクリプトから開始します。パッケージにインストール後スクリプトが含まれている場合、そのスクリプトはパッケージのインストール後またはアップグレード後に自動的に実行されます。開発者コンソールで、PostInstallScript Apex クラスを作成します。

public class PostInstallScript implements InstallHandler {
    
    // Deploy post-install metadata  
    public void onInstall(InstallContext context) {
        DeployMetadata deployUtil = new DeployMetadata();
        Metadata.DeployContainer container = deployUtil.constructDeploymentRequest();
        deployUtil.deploy(container);
    }
}
メモ

メモ

メタデータはインストール後スクリプトで取得およびリリースできます。ただし、アンインストールスクリプトでは、Apex コードからメタデータを取得できますが、リリースはできません。

これで終了です。各組織でパッケージをアップグレードすると、このスクリプトが新しい項目をすべてのページレイアウトに追加します。あなた (とシステム管理者) が、設定 UI で変更を行う必要は一切ありません。次の単元では、別のシナリオを確認します。複数組織で設定およびリリースする必要があるカスタムメタデータ項目を作成した場合はどうなるでしょうか?

まず、試してみましょう。次の Challenge を実行して知識をテストしましょう。

リソース