IBM iユーザーに捧げる

図表 4 SQL構文内のカラムを少し書き換える表示される5250画面を操作する。通常の5250画面と同じように、ログイン、プログラムの実行、ログアウトまで一連の操作を行う。
その際、表示される各画面にIDとAPIで使用したい入出力フィールドを指定し、実行キーやF3キーなどを押して画面遷移していくと、ARCAD APIが実行するシナリオが自動記録されていく仕組みである（図表5）。
プログラムの使用方法さえわかっていれば、プログラムの詳細な仕様の把握や改修作業は不要なので、自社アプリケーションだけでなく、パッケージ製品のプログラムやOS

図表 5 5250画面を動かしながら、ARCAD APIのシナリオを作成

で表示される画面からAPIを作成することも可能である。
CRUDに対応してAPIを作成する
作 成（Create）、読 み 出 し（Read）、更 新（Update）、削除（Delete）と、CRUDに対応してAPIを作成することも可能である。
CRUDに対応していない場合には、ユーザーが用途ごとに用意されたAPIのURLを把握しておく必要がある。しかAPI 入門

PART 3

ツール編

GoAnywhere MFT
株式会社ソルパック

APIをはじめシステム間の多彩な連携を司る連携ツール

データ連携機能を司る「プロジェクト」
を中心に双方向のAPIを作成
栃内 勇紀 田中 遥 株式会社ソルパック

Text＝しCRUDに対応していれば、HTTPのメソッドを指定して取得するAPIを切り替えられるので、把握しておくURLの数が少なくなる。
作成方法は、GET、POST、DELETE、PUTの各役割に対し、前述した5250画面操作を使用して作成したシナって少し書き換えるだけで完了である。

リオを当てはめるだけである（図表6）。

GoAnywhere MFT（以 下、GoAnywhere）と は、組

たとえば“SELECT ID, NAME FROM ライブラリ名/フ ァ イ ル 名”と い う SQL 構 文 の 場 合 は、“SELECT

以上の3種類が、ARCAD APIの提供するAPI作成方法で織内のすべてのファイル転送を単一のインターフェースで${o:ID:ID}, ${o:名前:NAME} FROM ライブラリ名/フある。作成したAPIは、Webアプリケーションやモバイル管理するソリューションである。ネットワーク内にGoAny

ァイル名”というように、APIで使用するフィールドに、アプリケーションなど他プラットフォームから呼び出して、where を導入することで、サーバー間のファイル転送の自IBM iと連携するために使用できる。

動化、個人間のファイル共有、コラボレーションを容易に${“o”:APIに出力する際のフィールド名:カラム名}を付けるだけで、設定は終わりである（図表4）。
このように、IBM iに詳しくない担当者でもSQLの経験さえあれば、簡単にAPIを作成できる。

ま た、IBM i OS の 機 能 と し て 新 た に 登 場 し た SQL

ステム／サービスのREST APIを実行する方法、および他システム／サービスにREST APIを提供する方法の具体的なステップを紹介する。

IBM i からREST APIを実行する方法
まず一般的にREST APIが提供する情報を例に、IBM iからREST APIを実行する方法を説明しよう。

実現する。
接続先側のAPI設定HTTP関数を活用すると、RPGなどに記載されたSQL構文

マルチプラットフォームに対応しており、IBM i への導からAPIにリクエストを投げられるので、IBM i間のデータ入も可能である（本稿では、IBM i へのGoAnywhere導入

一般にREST APIでは、サービスに応じて多様な認証方連携にも活用できる。

を前提とするが、導入先プラットフォームによる機能や管式が登場する。たとえばパスワード認証、APIトークン、セ理メニューに違いはない）。

ッション認証、OAuthなど。中でもAPIトークンのように、5250画面操作によりAPIを作成する
前述したSQL構文によるAPI作成方法は、物理ファイル

GoAnywhereは、クライアント機能とサーバー機能の双アプリケーション（この場合はRESTクライアント側となや論理ファイルなど大量データを取得したい場合に有効で方を備えている。クライアント機能はあらゆるシステムやるGoAnywhere）に対して固有のトークンをサービス側でサービスへ、GoAnywhereをクライアント側として接続し、事前生成する必要がある場合は、事前準備としてRESTマルチステップの連携処理を実行する（ファイル転送プロ

APIガイドに沿ってサービス側の設定を行う。

ある。しかしRPGで作成された一般的なプログラムは複数のDBから構成されていることが多く、これをすべてAPI化

図表 6 CRUDに対応したAPIを作成

トコル、データベース接続、API呼び出しなど）。

していくと、対象DBが多くなったり、プログラムの仕様の一方のサーバー機能は、GoAnywhereがファイル転送プ確認作業が発生したりと、時間やコストを要する。

ロトコルのサーバー側機能を提供する（FTPS、SFTP、

これに対して5250画面操作によるAPI作成方法は、

HTTPS、AS2、API化など）。

RPGやCOBOLなどによって5250画面上に表示された値からAPIを作成できる。そのためプログラムの仕様を知らなくても、プログラムの動かし方さえわかれば、APIを作成できるのが特徴である。
この場合は、ARCAD APIのGUIアプリケーション上に

106

GoAnywhere MFT とは2023 WINTER

API呼び出しの際にPOSTメソッドを指定した場合は、Createの処理をするシナリオが実行される、というように、各メソッドに既存のシナリオを割り当てるだけでCRUDに対応したAPIを作成できる

接続元側の設定
サービスごとにAPIのガイドの公開方法は異なる。一般的にインターネット上に公開されているパターン、契約者

GoAnywhereには、エンドユーザー自身で連携処理の定に限定で公開しているパターン、エンドユーザー／パート

義作成やAPIを作成するための管理インターフェースが提ナー向けなどさまざまだが、次のような構成で記載されて供されている。

いることが多い。

ここでは、IBM i 上に導入したGoAnywhere から他シ

2023 WINTER

107

・共通仕様（認証方式を含む）
・REST API一覧「RESTサーバ」として登録する（図表2）。
リソースの設定画面では、その場で接続可否を確かめる

HTTP メソッド

PUT

URI

/sample/update

リクエストボディ

data1
data2

サービス側の設定も済み、ガイドも手に入れ、いざ開発

ソースは一意の名称によって後述のプロジェクト（複数の連携処理からなる定義体）作成時に繰り返し呼び出せるではどのように開始するかを以下に説明する。

（APIキーなど、その他のリクエストヘッダが指定されている場合は後述のプロジェクト内で設定する）。

リソース登録プロジェクト作成

ト名、認証方式、リクエストヘッダのような情報が与えら「共通仕様」部分をリソースとして登録後は、「API一覧」れる。たとえば、図表1のような情報が共通仕様としてガで指示される内容に沿って連携処理をデザインする。一般

イドに示されている場合、GoAnywhere では事前定義の的に「API一覧」では、サービスに対するリソースの追加、接続設定「リソース」として登録する

取得、更新に必要なリクエストおよび期待されるレスポン「リソース」設定では、接続先となるサーバー、サービススを記載することが多い。のホスト名や認証情報を事前登録する。図表1のような情

たとえば、図表4 のようなAPI情報が提供されている場報が与えられた場合、GoAnywhere ではリソースタイプ

合、GoAnywhere では「プロジェクト」内で定義する（こ図表 5 プロジェクトデザイナー画面

リクエストためのテスト機能（図表3）が提供され、一度登録したリとなった場合に、IBM i 上に導入されているGoAnywhere

APIガイドの「共通仕様」を見ると、多くの場合はホス

図表 4 リソースを更新するAPIの例

レスポンス
ステータスコード

200

データ形式

JSON

レスポンスデータoutput_data1
output_data2

図表 6 Db2 for i とREST APIの連携パターン

IBM i

こでは図表1で与えられた共通仕様と関連のあるAPIとする）。
図表 1 APIガイドの共通仕様の例
URL

https://sample.com/sample/rest/v1

データ形式

JSON（API ごとに異なる値を指定する場合もあり）

認証方式

Basic

「プロジェクト」とは、複数の連携処理（ファイル連携、DB連携、API連携）の組み合わせからなる定義体の基本単位

GoAnywhereRPG

Db2 for i（Put ／ Post ／ Get）

REST APIJDBC（Select ／ Update ／ Insert）である。プロジェクトでは直観的に操作できるデザイナー
画面（図表5）が提供され、画面左側「コンポーネントラ
イブラリ」、画面中央「プロジェクトの概要」、画面右側の「作業ウインドウ」により構成される。
コンポーネントライブラリには、プロジェクトに含めら

図表 2 リソースタイプ「REST サーバ」の設定画面

REST← Call GoAnywhere→ Call RPG

図表 7 簡易シーケンス図

基幹システムGoAnywhereれる連携処理やローカルファイル処理などがリストされており（GoAnywhere では1つ1つの処理を「タスク」と呼①データベース接続（データ取得）

ぶ）、この中から必要な処理を選択して「プロジェクトの概②CSV書き込み要」に追加し、追加した処理の設定を「作業ウインドウ」③REST POST（CSVアップロード）で行う、といった操作で定義をデザインできる。
図表4のAPIが与えられた場合、具体的には図表5のサンクエストを送信し、「Read JSON」タスクでレスポンスのデータを読み込む。

レスポンス（JSON形式）④JSON読み込み（PROCESS IDの取得）

プル画面で示しているような「REST Put」タスクと「ReadJSON」タスクを組み合わせる。
「REST Put」タスクでリサービス

API Keyの発行

ループ処理

処理中：繰り返し完了、エラー：ジョブ終了or 後続処理

⑤REST GET（PROCESS IDで処理状況取得）⑥JSON読み込み（処理状況の読み込み）レスポンス（JSON形式）

こうした操作により、IBM i 上に導入したGoAnywhereからREST APIへの連携が実現する。5250画面上の操作
図表 3 リソース設定のテスト機能使用イメージは不要で、GoAnywhere の管理画面上のみで設定できるのがポイントである。
ただし実運用を考慮すると、APIへの連携のみで定義は直接JDBCで接続するパターンである。GoAnywhere はに複数のステップを要する場合が多い。認証に2つ以上の完結しない。リソースを更新するAPIであれば、Db2 for iいずれのパターンでも問題なく活用できるが、実装後の運ステップを要する場合もある。

からデータを取得する処理が必要であり、リソースを取得用を考えると、Db2 for iと直接接続するパターンのほうがするAPIであれば、取得したデータをDb2 for i に連携する管理はシンプルになる。
また、API連携そのものが複雑なケースも想定せねばな

処理の概要としては、Db2 for iのデータをCSVファイ

Db2 for iと連携するパターンは、大きく2つある（図表らない。本稿では極めて簡単な例を取り上げているが、実ルに変換し、REST APIを実行してCSVファイルをアップ6）。RPGと連携した処理のパターン、およびDb2 for iと際にはリクエストの送信、もしくは必要な情報を得るまでロードしている。アップロードしたCSVファイルは、サー処理も必要となる。

108

2023 WINTER

実際に起こり得る連携処理として、Db2 for iとの連携、および複数のAPI連携が必要な例を図表7に示した。

2023 WINTER

109

・共通仕様（認証方式を含む）
・REST API一覧「RESTサーバ」として登録する（図表2）。
リソースの設定画面では、その場で接続可否を確かめる

HTTP メソッド

PUT

URI

/sample/update

リクエストボディ

data1
data2

サービス側の設定も済み、ガイドも手に入れ、いざ開発

ソースは一意の名称によって後述のプロジェクト（複数の連携処理からなる定義体）作成時に繰り返し呼び出せるではどのように開始するかを以下に説明する。

（APIキーなど、その他のリクエストヘッダが指定されている場合は後述のプロジェクト内で設定する）。

リソース登録プロジェクト作成

ト名、認証方式、リクエストヘッダのような情報が与えら「共通仕様」部分をリソースとして登録後は、「API一覧」れる。たとえば、図表1のような情報が共通仕様としてガで指示される内容に沿って連携処理をデザインする。一般

イドに示されている場合、GoAnywhere では事前定義の的に「API一覧」では、サービスに対するリソースの追加、接続設定「リソース」として登録する

取得、更新に必要なリクエストおよび期待されるレスポン「リソース」設定では、接続先となるサーバー、サービススを記載することが多い。のホスト名や認証情報を事前登録する。図表1のような情

たとえば、図表4 のようなAPI情報が提供されている場報が与えられた場合、GoAnywhere ではリソースタイプ合、GoAnywhere では「プロジェクト」内で定義する（こ図表 5 プロジェクトデザイナー画面

リクエストためのテスト機能（図表3）が提供され、一度登録したリとなった場合に、IBM i 上に導入されているGoAnywhere

APIガイドの「共通仕様」を見ると、多くの場合はホス

図表 4 リソースを更新するAPIの例

レスポンス
ステータスコード

200

データ形式

JSON

レスポンスデータ

output_data1
output_data2

図表 6 Db2 for i とREST APIの連携パターン

IBM i

こでは図表1で与えられた共通仕様と関連のあるAPIとする）。
図表 1 APIガイドの共通仕様の例
URL

https://sample.com/sample/rest/v1

データ形式

JSON（API ごとに異なる値を指定する場合もあり）

認証方式

Basic

「プロジェクト」とは、複数の連携処理（ファイル連携、DB連携、API連携）の組み合わせからなる定義体の基本単位

GoAnywhereRPG

Db2 for i（Put ／ Post ／ Get）

REST APIJDBC（Select ／ Update ／ Insert）である。プロジェクトでは直観的に操作できるデザイナー
画面（図表5）が提供され、画面左側「コンポーネントラ
イブラリ」、画面中央「プロジェクトの概要」、画面右側の「作業ウインドウ」により構成される。
コンポーネントライブラリには、プロジェクトに含めら

図表 2 リソースタイプ「REST サーバ」の設定画面

REST← Call GoAnywhere→ Call RPG

図表 7 簡易シーケンス図

基幹システムGoAnywhereれる連携処理やローカルファイル処理などがリストされており（GoAnywhere では1つ1つの処理を「タスク」と呼①データベース接続（データ取得）

ぶ）、この中から必要な処理を選択して「プロジェクトの概②CSV書き込み要」に追加し、追加した処理の設定を「作業ウインドウ」③REST POST（CSVアップロード）で行う、といった操作で定義をデザインできる。
図表4のAPIが与えられた場合、具体的には図表5のサンクエストを送信し、「Read JSON」タスクでレスポンスのデータを読み込む。

レスポンス（JSON形式）④JSON読み込み（PROCESS IDの取得）

プル画面で示しているような「REST Put」タスクと「ReadJSON」タスクを組み合わせる。
「REST Put」タスクでリサービス

API Keyの発行

ループ処理

処理中：繰り返し完了、エラー：ジョブ終了or 後続処理

⑤REST GET（PROCESS IDで処理状況取得）⑥JSON読み込み（処理状況の読み込み）

レスポンス（JSON形式）

こうした操作により、IBM i 上に導入したGoAnywhereからREST APIへの連携が実現する。5250画面上の操作
図表 3 リソース設定のテスト機能使用イメージは不要で、GoAnywhere の管理画面上のみで設定できるのがポイントである。
ただし実運用を考慮すると、APIへの連携のみで定義は直接JDBCで接続するパターンである。GoAnywhere はに複数のステップを要する場合が多い。認証に2つ以上の完結しない。リソースを更新するAPIであれば、Db2 for iいずれのパターンでも問題なく活用できるが、実装後の運ステップを要する場合もある。

からデータを取得する処理が必要であり、リソースを取得用を考えると、Db2 for iと直接接続するパターンのほうがするAPIであれば、取得したデータをDb2 for i に連携する管理はシンプルになる。
また、API連携そのものが複雑なケースも想定せねばな

処理の概要としては、Db2 for iのデータをCSVファイ

Db2 for iと連携するパターンは、大きく2つある（図表らない。本稿では極めて簡単な例を取り上げているが、実ルに変換し、REST APIを実行してCSVファイルをアップ6）。RPGと連携した処理のパターン、およびDb2 for iと際にはリクエストの送信、もしくは必要な情報を得るまでロードしている。アップロードしたCSVファイルは、サー処理も必要となる。

108

2023 WINTER

実際に起こり得る連携処理として、Db2 for iとの連携、および複数のAPI連携が必要な例を図表7に示した。

2023 WINTER

109

を操作するためのAPIを作成する方法を紹

図表 8 Db2 for iとAPI連携を組み合わせたプロジェクトの例

図表 11

プロジェクトをAPI化する設定画面サンプル介する。

実行／自動化
プロジェクトをデザインしたあとは、実行を自動化する方法を検討する。

システム構成GoAnywhereは、スケジューラー、モ

まずシステム構成では（APIの公開範囲にもニター（フォルダ監視機能）、コマンドよるが）、IBM i に対する通信が要求される実行（IBM i、Windows、AIX、UNIX、ため、セキュリティ面を考慮する必要があLinux向け）、REST ／ SOAPなど、自る。GoAnywhere では、図表9に示す構成動化のオプションを複数提供している。

を提案している。

またGoAnywhere 上ではジョブキ

ここではIBM i に導入したGoAnywhereューも提供しており、優先度に応じてとGoAnywhere Gatewayを組み合わせて複数のジョブを柔軟に管理できる。

い る。GoAnywhere Gateway

は、

IBM i 上の実装では、GoAnywhere

GoAnywhere とインターネット間のリバ実行コマンドをCLプログラム／ RPGースプロキシとして稼働し、DMZへの導入

ビス側でバッチ処理されるが、処理状況を確認するAPIをに組み込んだ自動化、もしくはGoAnywhere のスケジュを想定している。GoAnywhere Gateway

繰り返し実行することで、正常に処理が終了しているかをーラーをベースとした自動化が多く利用される。

からGoAnywhere へは通信を行うことなく、検知している。
この処理に従って作成したプロジェクトが、図表8である。定義の複雑性はあるものの、1つのプロジェクトのみ他のシステム／サービスからIBM iを操作するためのAPI作成方法
次に、他のシステムやサービスからIBM i 上のリソースで、Db2 for iとAPI の連携を完結できる。

REST を有効化すると、API を使用するためのガイド（ヘルプ）が表示される

図表 12

Postman によるAPI実行イメージ

外部からAPIへのアクセスを可能とする。
APIの作成システム構成が決まれば、簡単にAPIを作成できる。前述したプロジェクトを用いるが、このプロジェクトではRESTでの呼図表 9 GoAnywhere によるAPI作成時のシステム構成例

Get ／ Post ／ Put

JSON ／ XML

GoAnywhere
Gateway

び出しが可能なので、レスポンスなどの拡張設定を行うだけでAPIを作成できる。

IBM i●プロジェクトの作成

GoAnywhere
REST APIDb2 for i

他システムからRESTで呼び出された場合、プロジェクトがDb2 for iなどと対話する。プロジェクトの作成方法は前述したとクライアントおりで、API化を想定した場合、クライアントからの入力使用するためのヘルプ画面などもある。

値とクライアントへのレスポンスを意識した定義を行う。
図表 10

API化を想定したプロジェクトのサンプル画面

入力値はDb2 for iへの問い合わせのキー項目や、データ以上が、GoAnywhere によってIBM i 上のリソースを処理の入力値に使用したり、レスポンスはプロジェクト内操作するためのAPIを提供する手順となる。実際にサンプの一連の処理で出力されたデータを用いるのが一般的であルで使用したAPI（2つの入力値から製品マスターを参照しる。て製品名を取得）を実行したのが、図表12である。

簡易な例として、2つの入力値からDb2 for i へ問い合わ

処理成功時のレスポンスの定義（メッセージに任意のデータを指定できる）
例）Db2 for i で取得したデータをレスポンスとして設定せを行い、取得したデータをレスポンスに設定したプロジ

本稿では、IBM i 上に導入したGoAnywhere によって

ェクトのサンプル画面が図表10である。入力値は変数としREST API を実行する手順、またそれとは逆に、IBM i のて定義し、レスポンスは専用の設定項目を使用する。

リソースを外部から操作するAPI作成の手順を示した。
どちらの場合もデータ連携機能を司る「プロジェクト」●プロジェクトのAPI有効化
Db2 for i 接続定義例）入力値から Db2 for i へ問い合わせを行う処理

プロジェクトを作成したら、API化のための設定を行う。

を中心に、Db2 fo iと対話するシンプルな例で説明したが、より複雑な要件にも対応可能である。

プロジェクトのAPI化専用の管理メニュー上で、入力値（API実行時のリクエストボディのパラメータとなる）や使用ユーザーなどを設定する（図表11）。REST APIの有効化もチェックボックスだけで設定でき、有効化後はAPIを110

2023 WINTER

2023 WINTER

111

を操作するためのAPIを作成する方法を紹

図表 8 Db2 for iとAPI連携を組み合わせたプロジェクトの例

図表 11

プロジェクトをAPI化する設定画面サンプル介する。

実行／自動化
プロジェクトをデザインしたあとは、実行を自動化する方法を検討する。

システム構成GoAnywhereは、スケジューラー、モ

まずシステム構成では（APIの公開範囲にもニター（フォルダ監視機能）、コマンドよるが）、IBM i に対する通信が要求される実行（IBM i、Windows、AIX、UNIX、ため、セキュリティ面を考慮する必要があLinux向け）、REST ／ SOAPなど、自る。GoAnywhere では、図表9に示す構成動化のオプションを複数提供している。

を提案している。

またGoAnywhere 上ではジョブキ

ここではIBM i に導入したGoAnywhereューも提供しており、優先度に応じてとGoAnywhere Gatewayを組み合わせて複数のジョブを柔軟に管理できる。

い る。GoAnywhere Gateway

は、

IBM i 上の実装では、GoAnywhere

GoAnywhere とインターネット間のリバ実行コマンドをCLプログラム／ RPGースプロキシとして稼働し、DMZへの導入

ビス側でバッチ処理されるが、処理状況を確認するAPIをに組み込んだ自動化、もしくはGoAnywhere のスケジュを想定している。GoAnywhere Gateway

繰り返し実行することで、正常に処理が終了しているかをーラーをベースとした自動化が多く利用される。

からGoAnywhere へは通信を行うことなく、検知している。
この処理に従って作成したプロジェクトが、図表8である。定義の複雑性はあるものの、1つのプロジェクトのみ

他のシステム／サービスからIBM iを操作するためのAPI作成方法
次に、他のシステムやサービスからIBM i 上のリソースで、Db2 for iとAPI の連携を完結できる。

REST を有効化すると、API を使用するためのガイド（ヘルプ）が表示される

図表 12

Postman によるAPI実行イメージ

外部からAPIへのアクセスを可能とする。
APIの作成システム構成が決まれば、簡単にAPIを作成できる。前述したプロジェクトを用いるが、このプロジェクトではRESTでの呼図表 9 GoAnywhere によるAPI作成時のシステム構成例

Get ／ Post ／ Put

JSON ／ XML

GoAnywhere
Gateway

び出しが可能なので、レスポンスなどの拡張設定を行うだけでAPIを作成できる。

IBM i●プロジェクトの作成

GoAnywhere
REST APIDb2 for i

他システムからRESTで呼び出された場合、プロジェクトがDb2 for iなどと対話する。プロジェクトの作成方法は前述したとクライアントおりで、API化を想定した場合、クライアントからの入力使用するためのヘルプ画面などもある。

値とクライアントへのレスポンスを意識した定義を行う。
図表 10

API化を想定したプロジェクトのサンプル画面

入力値はDb2 for iへの問い合わせのキー項目や、データ以上が、GoAnywhere によってIBM i 上のリソースを処理の入力値に使用したり、レスポンスはプロジェクト内操作するためのAPIを提供する手順となる。実際にサンプの一連の処理で出力されたデータを用いるのが一般的であルで使用したAPI（2つの入力値から製品マスターを参照しる。て製品名を取得）を実行したのが、図表12である。

簡易な例として、2つの入力値からDb2 for i へ問い合わ

処理成功時のレスポンスの定義（メッセージに任意のデータを指定できる）
例）Db2 for i で取得したデータをレスポンスとして設定せを行い、取得したデータをレスポンスに設定したプロジ

本稿では、IBM i 上に導入したGoAnywhere によってェクトのサンプル画面が図表10である。入力値は変数としREST API を実行する手順、またそれとは逆に、IBM i のて定義し、レスポンスは専用の設定項目を使用する。

リソースを外部から操作するAPI作成の手順を示した。
どちらの場合もデータ連携機能を司る「プロジェクト」●プロジェクトのAPI有効化
Db2 for i 接続定義例）入力値から Db2 for i へ問い合わせを行う処理

プロジェクトを作成したら、API化のための設定を行う。

を中心に、Db2 fo iと対話するシンプルな例で説明したが、より複雑な要件にも対応可能である。

プロジェクトのAPI化専用の管理メニュー上で、入力値（API実行時のリクエストボディのパラメータとなる）や使用ユーザーなどを設定する（図表11）。REST APIの有効化もチェックボックスだけで設定でき、有効化後はAPIを

110

2023 WINTER

2023 WINTER111