クリアフィルター
お知らせ
Mihoko Iijima · 2020年9月15日
開発者の皆さん、こんにちは!
Full Stack コンテストについての続報をお伝えします!
投票期間に追加ポイントを獲得できる「テクノロジーボーナス」について紹介します。
対象となる技術は、以下の通りです。
InterSystems IRIS REST API の使用
InterSystems Native API の使用
InterSystems JDBC の使用
ZPMパッケージによる公開
Docker コンテナの使用
詳細は以下の通りです。
InterSystems IRIS REST API の使用 - 1 point
フルスタック・アプリケーションから、REST API 経由で InterSystems IRIS にアクセスるとボーナスポイントを獲得できます。REST API をご自身で開発されるか、組み込みのものを利用したり、ZPM 経由でインストールするなど、選択できます。
RESTサービス作成方法については、ドキュメントや IRIS で作成する REST サーバの仕組み をご参照ください。
InterSystems Native API の使用 - 1 point
InterSystems Native API(.NET、Java、Python、Node.js)のいずれかを使用してフルスタック・アプリケーションのデータにアクセスすると、テクノロジーボーナスを獲得できます。詳細はこちらのドキュメントの「Native API for xxx の使用法」のリンク先をご参照ください。
InterSystems JDBC の使用 - 1 point
InterSystems IRIS では、JDBC ドライバを提供しています。SQL と InterSystems JDBC を使用してフルスタック・アプリケーションのデータ参照を行うことでテクノロジボーナスが獲得できます。
JDBC ドライバの使用法についてはドキュメントをご参照ください。
ZPM パッケージによる公開と使用 - 1 point
フルスタック・アプリケーション用に ZPM(ObjectScript Package Manager)パッケージをビルドして公開し、それを利用してデプロイできるように開発されると、テクノロジーボーナスが獲得できます。
ZPM クライアントがインストールされている IRIS でのコマンド実行例は以下の通りです。
zpm "install your-full-stack-solution-name"
詳細は、ZPM クライアントのドキュメントをご参照ください。
Docker container usage - 1 point
フルスタック・アプリケーションに Docker コンテナで実行する InterSystems IRIS を使用すると「Docker コンテナ」ボーナスを獲得できます。
コンテナ作成用の開発テンプレートを公開しています。以下のいずれかのテンプレートを使用して開発された場合、ボーナスポイントを獲得できます。
Basic InterSystems IRIS Docker template /使い方解説ビデオ(日本語)
IRIS REST API template /使い方解説ビデオ(日本語)(13:00~)
Native API template /使い方解説ビデオ(日本語)
IntegratedML template/ 使い方解説ビデオ(日本語)(00:46~17:55)
IRIS Analytics template
掲載されている技術を使ってみたい方、何かお困りのことがあればぜひ開発者コミュニティへご質問ください!
記事
Tomohiro Iwamoto · 2020年6月29日
ここ数年の間、ハイパーコンバージドインフラストラクチャ(HCI)ソリューションが勢いを増しており、導入件数が急速に増加しています。 IT部門の意思決定者は、VMware上ですでに仮想化されているアプリケーションなどに対し、新規導入やハードウェアの更新を検討する際にHCIを考慮に入れています。 HCIを選択する理由は、単一ベンダーと取引できること、すべてのハードウェアおよびソフトウェアコンポーネント間の相互運用性が検証済みであること、IO面を中心とした高いパフォーマンス、単純にホストを追加するだけで拡張できること、導入や管理の手順が単純であることが挙げられます。
この記事はHCIソリューションの一般的な機能を取り上げ、HCIを初めて使用する読者に紹介するために執筆しました。 その後はデータベースアプリケーションの具体的な例を使用し、InterSystems データプラットフォーム上に構築されたアプリケーションを配置する際の、キャパシティプランニングとパフォーマンスに関する構成の選択肢と推奨事項を確認します。 HCIソリューションはパフォーマンスを向上させるためにフラッシュストレージを利用しているため、選択されたフラッシュストレージオプションの特性と使用例に関するセクションも含めています。
この記事のキャパシティ計画とパフォーマンスに関する推奨事項は、VMWare vSANに特化しています。 ただし、HCI市場で成長しているのはvSANだけではなく、同じく導入件数が増加しているNutanixをはじめとする他のHCIベンダーも存在します。 選択したHCIベンダーにかかわらず多くの機能は共通しているため、この記事の推奨事項は広く適用できます。 ただし、どの場合もアプリケーション固有の要件を考慮しながらHCIベンダーとこの記事の推奨事項について話し合うことが得策です。
InterSystems データプラットフォームとパフォーマンスに関する他の連載記事のリストはこちらにあります。
HCIとは?
厳密に言えばコンバージドソリューションは以前から長らく存在しますが、この記事ではWikipediaに「ハイパーコンバージェンスはパッケージ化された複数の個別システムから、市販されている商用x86ラックサーバーですべてが実行されるソフトウェア定義のインテリジェントな環境に進化している…」と記載されているような最新のHCIソリューションを取り上げています。
では、HCIは単独で存在するものなのでしょうか?
違います。 ベンダーに相談する際は、HCIには多くの置き換え可能な要素があることを覚えておく必要があります。コンバージドとハイパーコンバージドは具体的な青写真や標準ではなく、どちらかといえば一種のアーキテクチャなのです。 HCIハードウェアには商品性があるため、市場では複数のベンダーがソフトウェアレイヤーのほか、コンピューティング機能、ネットワーク機能、ストレージ機能、管理機能を組み合わせたその他の革新的な方法を使って差別化を図っています。
ここではあまり深追いしませんが、HCIの名が付いたあるソリューションでは、クラスター内の複数サーバー内にストレージを配置したり、サーバーのクラスターと独立したSANストレージ(複数の異なるベンダー製のものである可能性もあります)を使ったより普通の構成を作ることができます。これらはまた、相互運用性がテストおよび検証されており、単一のコントロールプレーンから管理できます。 キャパシティとパフォーマンスを計画する際は、ストレージがSANファブリック(ファイバーチャネルやイーサネットなど)を介して接続されたアレイにあり、ストレージプールがソフトウェアで定義され、サーバーノードの各クラスター内に配置され、複数のサーバー上でストレージが処理される場合とは異なるパフォーマンスと要件を備えたソリューションを検討する必要があります。
では、改めてHCIとは何でしょうか?
この記事ではHCI、特にストレージが物理的にホストサーバー内にあるVMware vSANに焦点を当てています。 このようなソリューションでは、HCIソフトウェアレイヤーが処理を実行するクラスター内の複数のノードのそれぞれの内部ストレージを1つの共有ストレージシステムのように機能させています。 そのため、HCIソフトウェアにコストがかかったとしても、エンタープライズストレージアレイを使用するソリューションと比較して、HCIを使用すると大幅にコストを節約できる可能性があることがHCIを採用するもう一つの要因となっています。
この記事では、HCIがコンピューティング、メモリ、ストレージ、ネットワーク、および管理ソフトウェアを仮想化したx86サーバーのクラスターに統合するソリューションについてご紹介します。
一般的なHCIの特徴
上記のとおり、HCIソリューションの一例にはVMWare vSANとNutanixがあります。 どちらもHCIに対して類似した高レベルのアプローチを採用しており、良い典型例だと言えます。
VMware vSAN にはVMware vSphereが必要であり、複数のベンダーのハードウェアで利用できます。 利用可能なハードウェアの選択肢は多数ありますが、これらはVMwareのvSANハードウェア互換性リスト(HCL)に厳密に依存しています。 ソリューションは、パッケージ化および事前構成されたEMC VxRailなどで購入できます。または、HCLでコンポーネントを購入して独自に構築することもできます。
Nutanixは、最大で2U、4ノードのアプライアンスを構成済みブロック化したハードウェアを含むオールインワンソリューションとして購入および導入することもできます。 Nutanixソリューションは、他のベンダーのハードウェアで検証された独自のソフトウェアソリューションとしても利用できます。
実装にはいくつかのバリエーションがありますが、一般的にHCIにはパフォーマンスとキャパシティの計画に関して、あなたが知っておくべき一般的な特徴があります。
仮想マシン(VM)はVMware ESXiなどのハイパーバイザーで実行されますが、Hyper-VやNutanix Acropolis Hypervisor(AHV)などのハイパーバイザーでも実行されます。 NutanixはESXiを使用して導入することもできます。
ホストサーバーは多くの場合、コンピューティング、ストレージ、ネットワークのブロックに統合されます。 例えば、4つのノードを持つ2Uアプライアンスがあります。
管理と可用性のために、複数のホストサーバーがクラスターに統合されます。
ストレージは階層化されており、オールフラッシュ、またはフラッシュキャッシュ層とキャパシティ層として利用する回転式ディスクとのハイブリッドになっています。
ストレージは、容量、パフォーマンス、可用性を確保するためのデータ配置とポリシーを含むソフトウェア定義のプールとして表現されます。
容量とIOのパフォーマンスは、クラスターにホストを追加することでスケーリングされます。
データは複数のクラスターノード上のストレージに同期的に書き込まれるため、クラスターはデータを失うことなくホストやコンポーネントの障害に耐えることができます。
VMの可用性とロードバランシングは、vMotion、VMware HA、DRSなどのハイパーバイザーによって提供されます。
上記の通り、外部ストレージアレイ、ストレージ専用ノードのサポートなど、このリストに変更を加えた他のHCIソリューションもあります。このリストはベンダーのリストと同じく長いです。
HCIの採用が加速し、ベンダー間の競争がイノベーションとパフォーマンスの向上を推進しています。 HCIがクラウドを導入するための基本的要素になっていることも注目に値します。
InterSystemsの製品はHCIでサポートされていますか?
オペレーティングシステムが仮想化されている場合を含め、さまざまなプロセッサのタイプとオペレーティングシステムに対してInterSystemsの製品を検証およびリリースするのは、InterSystemsのポリシーであり、決まりでもあります。 詳細については、InterSystemsサポートポリシーおよびリリース情報を参照してください。
例えばx86ホスト上のvSANの場合、Caché 2016.1をRed Hat 7.2オペレーティングシステム上で実行することができます。
注意:独自のアプリケーションを作成しない場合は、アプリケーションベンダーのサポートポリシーも確認する必要があります。
vSANキャパシティプランニング
このセクションでは、Caché、Ensemble、HealthShareなどのInterSystemsデータプラットフォーム上のデータベースアプリケーションにVMware vSANを導入する場合の考慮事項と推奨事項について説明します。 ただし、これらの推奨事項はHCIベンダーと検討するための一般的な構成関連の質問リストとして使用することもできます。
VM vCPUとメモリ
まず、複数の同じプロセッサを持つVMware ESXiにアプリケーションを導入するためにすでに使用中のものと同じキャパシティプランニングのルールをデータベースVMのvCPUとメモリに使用します。
Cachéの一般的なCPUとメモリのサイジングについて復習するには、この連載の他の記事のリスト「キャパシティ計画とパフォーマンスに関する連載の索引」を参照してください。
HCIシステムの特徴の1つに、非常に低いストレージIOレイテンシと高いIOPS機能があります。 この連載の第2回目の投稿にあった、CPU / メモリ / ストレージ / ネットワークを示すハードウェアの食品群の図を覚えていらっしゃるかもしれません。 その記事ではこれらのコンポーネントがすべて相互に関連しているため、1つのコンポーネントに対する変更が別のコンポーネントに影響する可能性があり、予期しない結果が生じることがあることを指摘していました。 例えば、私はストレージアレイの特にひどいIOボトルネックを解消するとCPU使用率が100%に跳ね上がり、ユーザーエクスペリエンスがさらに悪化した事例を見たことがあります。これは、システムが突然自由に作業量を増やせるようになったものの、ユーザー活動とスループットの増加に対応するためのCPUリソースがなかったために発生したものです。 新しいシステムを計画する際、サイジングモデルがパフォーマンスの低いハードウェアのパフォーマンスメトリックに基づいている場合はこのような影響を考慮する必要があります。 新しいプロセッサを搭載した新しいサーバーにアップグレードする場合でも、新しいプラットフォームでのIOレイテンシが低いために適切なサイズにする必要がある場合は、データベースVMの動作を注意深く監視する必要があります。
また、後述するように物理ホストのCPUリソースとメモリリソースをサイジングする際はソフトウェア定義のストレージIO処理も考慮する必要があります。
ストレージキャパシティプランニング
ストレージキャパシティプランニングを理解し、データベースの推奨事項を理解するには、まずvSANと従来のESXiストレージの基本的な違いを理解する必要があります。 最初にこれらの違いを説明し、次にCachéデータベースに関するすべてのベストプラクティスの推奨事項を詳しく説明します。
vSANストレージモデル
vSANおよびHCIでは、一般的にソフトウェア定義ストレージ(SDS)が重要な役割を果たしています。 データの保存方法と管理方法は、ESXiサーバーのクラスターと共有ストレージアレイを使用する場合とは大きく異なります。 HCIの利点の1つはLUNがないことです。その代わり、必要に応じてVMに割り当てられるストレージのプールがあり、VMDKごとに可用性、容量、およびパフォーマンスの機能を表すポリシーが適用されています。
例えば、パフォーマンスと可用性の要件に応じて、ディスクの数やタイプが異なるさまざまなサイズのディスクグループやディスクプールにまとめられた回転式ディスクのシェルフで構成された従来のストレージアレイを想像してください。 その後、ディスクグループは多数の論理ディスク(ストレージアレイボリュームまたはLUN)として表現され、データストアとしてESXiホストに提示され、VMFSボリュームとしてフォーマットされます。 VMはデータストア内のファイルとして表現されます。 可用性とパフォーマンスに関するデータベースのベストプラクティスでは、データベース(ランダムアクセス)、ジャーナル(シーケンシャル)、およびその他(バックアップや非本番システムなど)用に、少なくとも独立したディスクグループとLUNを使用することを推奨しています。
vSANの場合はそうではありません。vSANのストレージは、ストレージポリシーベースの管理(SPBM)を使用して割り当てられます。 ポリシーは、以下を含む機能を組み合わせて作成できます(ただし、これ以外の機能もあります)。
冗長なデータのコピー数を決める許容障害数(FTT)。
容量を節約するイレイジャーコーディング(RAID-5またはRAID-6)。
パフォーマンスを向上させるディスクストライプ。
シックまたはシンディスクプロビジョニング(vSANではデフォルトでシン)。
その他...
VMDK(個々のVMディスク)は適切なポリシーを選択することにより、vSANストレージプールから作成されます。 したがって、属性を設定してアレイ上にディスクグループとLUNを作成するのではなく、SPBMを使用してストレージの機能をvSANのポリシーとして定義します。例えば、「データベース」は「ジャーナル」やその他の必要なものとは異なります。 VM用のディスクを作成する際は容量を設定し、適切なポリシーを選択します。
もう一つ重要な概念があります。VMはVMDKデータストア上のファイルのセットではなく、ストレージオブジェクトのセットとして保存されます。 例えば、データベースVMはVMDK、スワップ、スナップショットなどを含む複数のオブジェクトとコンポーネントで構成されます。vSAN SDSは選択したポリシーの要件を満たすため、すべてのオブジェクト配置メカニズムを管理します。
ストレージ階層とIOパフォーマンスのプランニング
高いパフォーマンスを確保するため、2つの階層のストレージがあります。
キャッシュ層 - 高耐久性フラッシュである必要があります。
キャパシティ層 - フラッシュ、またはハイブリッドの場合は回転式ディスクを使用します。
下の図に示すように、ストレージは複数の階層とディスクグループに分かれています。 vSAN 6.5では、各ディスクグループに単一のキャッシュデバイスと最大7台の回転式ディスクまたはフラッシュデバイスが含まれます。 最大5つのディスクグループを使用できるため、ホストごとに最大35台のデバイスを使用できます。 次の図は、4つのホストを持つオールフラッシュvSANクラスターを示しています。各ホストには2つのディスクグループがあり、それぞれに1台のNVMeキャッシュディスクと3台のSATAキャパシティディスクがあります。
図1. それぞれの層とディスクグループを示すvSANオールフラッシュストレージ
それぞれの層の設定方法やキャッシュ層とキャパシティ層に使うフラッシュのタイプを検討する場合、IOパスを考慮する必要があります。レイテンシを最小にしてパフォーマンスを最大にするため、書き込みはキャッシュ層に移され、ソフトウェアがその書き込みをまとめてキャパシティ層に移します。 キャッシュの使用状況は導入モデルに依存します。例えばvSANハイブリッド構成の場合はキャッシュ層の30%が書き込みキャッシュですが、オールフラッシュの場合はキャッシュ層の100%が書き込みキャッシュで、読み込みは低レイテンシなフラッシュキャパシティ層から行われます。
オールフラッシュを使用すると、パフォーマンスが向上します。 大容量で耐久性のあるフラッシュドライブが利用できるようになった今、回転式ディスクが必要かどうかを検討する必要があります。 近年のビジネス事例では回転式ディスクの代わりにフラッシュが採用されており、はるかに低いIOPS単位のコスト、パフォーマンス(低レイテンシ)、高信頼性(可動部品が故障せず、必要なIOPSで故障するディスクが少ない)、低電力かつ低発熱なプロファイル、小さな設置面積などを特徴としています。 また、その他のHCI機能のメリットも得られます。例えばvSANでは、オールフラッシュ構成でのみ重複排除と圧縮が許可されます。
推奨: 最高のパフォーマンスとTCOの削減のため、オールフラッシュを検討してください。
最高のパフォーマンスを得るには、特にvSANの場合はディスクグループごとにキャッシュデバイスが1つしかないため、キャッシュ層のレイテンシを最低にする必要があります。
推奨: SASでも問題ありませんが、可能であればキャッシュ層にNVMe SSDを選択してください。
推奨: キャッシュ層で高耐久性フラッシュデバイスを選択し、高負荷なI/Oを処理するようにしてください。
キャパシティ層のSSDについては、SAS SSDとSATA SSDの性能の差はごくわずかです。 データベースアプリケーションについては、キャパシティ層でNVMe SSDのコストを負担する必要はありません。 ただし、いかなる場合も、電源障害保護などの機能を備えたエンタープライズクラスのSATA SSDを使用するようにしてください。
推奨: キャパシティ層には大容量のSATA SSDを選択してください。
推奨: 電源障害保護機能を備えたエンタープライズSSDを選択してください。
スケジュールによってはIOPSが高い3D Xpointなどの新しいテクノロジーを使用し、レイテンシを下げ、容量を増やし、耐久性を高めることができます。 この記事の最後に、フラッシュストレージの構成を記しています。
推奨: キャッシュ層とキャパシティ層には、3D Xpointなどの新しいテクノロジーを組み込むことを検討してください。
前述したように、ホストごとに最大5つのディスクグループを作成でき、ディスクグループのキャパシティ層は1台のフラッシュデバイスと最大7台のデバイスで構成されます。 1台のフラッシュデバイスかつ必要な容量の単一のディスクグループ、またはホストごとに複数のディスクグループを作成できます。 ホストごとに複数のディスクグループを持たせると、次のようなメリットがあります。
パフォーマンス:階層内に複数のフラッシュデバイスがあると、ホストごとのIOPSが増加します。
障害ドメイン:キャッシュディスクの障害はディスクグループ全体に影響しますが、vSANが自動的に再構築されるため、可用性は維持されます。
可用性、パフォーマンス、容量のバランスをとる必要がありますが、一般的にはホストごとに複数のディスクグループを用意することをお勧めします。
推奨: ストレージの要件を確認し、ホストごとに複数のディスクグループを用意することを検討してください。
どのようなパフォーマンスを期待できますか?
アプリケーションのユーザーエクスペリエンスを向上させるには、ストレージのレイテンシを下げることが重要です。通常は、データベースの読み取りIOのレイテンシを10ミリ秒未満にすることが推奨されています。詳細については、この連載のパート6の表を参照してください。
既定のvSANストレージポリシーとCaché RANREADユーティリティを使用してCachéデータベースのワークロードをテストした結果、キャパシティ層でIntel S3610 SATA SSDを使用したオールフラッシュvSANのレイテンシは1ミリ秒未満で、3万IOPS超のランダムな読み取りIOが100%持続されることを確認しました。 Cachéデータベースが基本的に可能な限り多くのデータベースIOにメモリを使用するようにインスタンスをサイジングすることを考慮すれば、オールフラッシュのレイテンシとIOPS能力はほとんどのアプリケーションに十分な余裕を与えるものです。 メモリのアクセス時間は、NVMeフラッシュストレージよりも桁違いに短いことを覚えておいてください。
いつものことですが、何が最適なのかは状況によって違います。ストレージポリシー、ディスクグループの数、ディスクの数とタイプなどがパフォーマンスに影響するため、ご自身のシステムで検証してください!
キャパシティとパフォーマンスのプランニング
vSANストレージプールの物理容量(TB)は、キャパシティ層のディスクの合計サイズとして大まかに計算できます。 図1の構成例では、合計24個のINTEL S3610 1.6 TB SSDがあります。
クラスターの物理容量:24 x 1.6TB = 38.4 TB
ただし、利用可能な容量は選択する構成によって大きく異なり、計算が煩雑になります。例えば、使用されるポリシー(データのコピー数を指定するFTTなど)のほか、重複排除や圧縮が有効になっているかどうかによって決まります。
ここでは選択されたポリシーを段階的に追い、その容量とパフォーマンスへの影響とデータベースのワークロードに関する推奨事項について説明します。
私が目にするあらゆるESXiの導入環境は、複数のVMで構成されています。例えば、統合医療情報システムであるTrakCareはInterSystemsの医療情報プラットフォーム上に構築されており、HealthShareの中核には「ティア1ビジネスクリティカルアプリケーション」の説明に完全に適合する少なくとも1台の大規模(モンスター)データベースサーバーVMがあります。 ただし、導入環境には本番ウェブサーバー、プリントサーバーなど、単一の目的を持つ他のVMも混在しています。 テスト用、トレーニング用、および本番用ではないその他のVMもです。 通常、すべてが単一のESXiクラスターに導入されます。 ここではデータベースVMの要件に焦点を当てていますが、SPBMはすべてのVMに対してVMDKごとに調整できることを覚えておいてください。
重複排除と圧縮
vSANの場合、重複排除と圧縮はクラスター全体でオン/オフします。 重複排除と圧縮は、オールフラッシュ構成を使用している場合にのみ有効にできます。 両方の機能を同時に有効にできます。
一見すると、重複排除と圧縮は良い考えのように思えます。キャパシティ層で(より高価な)フラッシュデバイスを使用している場合は特に容量を節約したいものです。 重複排除と圧縮を有効にすると容量を節約できますが、大規模な本番データベースや常にデータが上書きされているクラスターではこの機能を有効にしないことをお勧めします。
重複排除と圧縮によってホストの処理負荷が1桁の%CPU使用率の範囲で増加する可能性がありますが、それはデータベースに推奨されない主な理由ではありません。
要約すると、vSANは4Kブロックを使用する単一ディスクグループ内のキャパシティ層にデータが書き込まれるときにデータの重複排除を試みます。 したがって、図1の例では重複排除するデータオブジェクトは、同じディスクグループのキャパシティ層に存在していなければなりません。 一意のポインタやコンテンツなどを含む8Kのデータベースブロックで埋められた基本的に巨大なファイルであるCachéデータベースファイルの容量が大幅に減るとは思えません。 また、vSANは重複ブロックの圧縮のみを試み、圧縮率が50%以上に達した場合にのみブロックが圧縮されたと見なします。 重複排除されたブロックが2Kに圧縮されない場合は、圧縮されずに書き込まれます。 オペレーティングシステムや他のファイルに重複がある場合がありますが、重複排除と圧縮の本当のメリットはVDI用に導入されたクラスターにあります。
また、重複排除と圧縮が有効になっている場合、ディスクグループ内の1台のデバイスの(まれではありますが)障害がグループ全体に影響を及ぼすことにも注意すべきです。 ディスクグループ全体が「異常」とマークされると、クラスター全体に影響があります。グループが異常とマークされると、ディスクグループ上のすべてのデータがそのグループから他の場所に退避され、その後はデバイスを交換しなければならず、vSANはリバランスするためにオブジェクトを再同期します。
推奨: データベースの導入では、圧縮と重複排除を有効にしないでください。
補足:InterSystemsのデータベースミラーリングについて。
最高の可用性を必要とするミッションクリティカルなティア1のCachéデータベースアプリケーションインスタンスの場合、仮想化されている場合でもInterSystemsの同期データベースミラーリングをお勧めします。仮想化ソリューションにはHAが組み込まれています。例えばVMWare HAの場合、ミラーリングを使用すると次のようなメリットもあります。
最新データの独立したコピーが存在します。
秒単位でフェイルオーバーできます(VMを再起動してからオペレーティングシステムを起動し、Cachéをリカバリするよりも高速です)。
アプリケーション/Cachéに障害が発生した場合(VMwareでは検出されません)にフェイルオーバーできます。
同じクラスターでデータベースをミラーリングしている場合に重複排除を有効にすると、問題があることに気付きましたか? ミラーデータの重複排除を試すことは 一般的には賢明ではなく、処理のオーバーヘッドも発生します。
HCIでデータベースをミラーリングするかどうかを決定する際は、必要な合計ストレージ容量を考慮する必要があります。 vSANは可用性を確保するためにデータのコピーを複数作成します。このデータストレージもミラーリングによって複製されます。 ストレージの追加コストと、VMware HAによるわずかな稼働時間の増加を天秤に掛ける必要があります。
稼働時間を最大にするため、2つのクラスターを作成し、データベースミラーの各ノードを完全に独立した障害ドメインに配置できます。 ただし、このレベルの稼働時間を提供するには、サーバーとストレージの合計容量に注意してください。
暗号化
また、保管データの暗号化方法も考慮する必要があります。 IOスタックには、次のようないくつかの選択肢があります。
Cachéのデータベース暗号化を使用する(データベースの暗号化のみ)。
ストレージで暗号化する(SSDでのハードウェアディスク暗号化など)。
暗号化がパフォーマンスに与える影響はごくわずかですが、HCIで重複排除または圧縮を有効にすると容量に大きな影響を与える可能性があります。 重複排除や圧縮を選択した場合、暗号化されたデータは設計上ランダムであり、十分に圧縮されないため、Cachéのデータベース暗号化を使用することは望ましくありません。 保護対象の場所や回避したいリスク(ファイルの盗難とデバイスの盗難のどちらを危険視するかなど)を検討してください。
推奨: 最低限の暗号化を行うには、可能な限り最下層のIOスタックで暗号化してください。 ただし、回避したいリスクが多くなるほど、スタックの階層は高くなります。
許容障害数(Failures To Tolerate, FTT)
FTT は、ストレージオブジェクトにクラスター内で少なくともn件のホスト、ネットワーク、またはディスクの障害が同時に発生してもオブジェクトの可用性を確保するようストレージに要件を設定します。 デフォルトは1(RAID-1)です。VMのストレージオブジェクト(VMDKなど)はESXiホスト間でミラーリングされます。
したがって、vSAN構成には少なくともn + 1個の複製(データのコピー)が含まれている必要があります。これは、クラスター内に2n + 1台のホストがあることも意味します。
例えば許容障害数が1のポリシーに従うには、たとえ1台のホストに障害が発生したとしても常に最低3台のホストを稼働させておく必要があります。 したがって、1台のホストがオフラインになったときのメンテナンスやその他の時間を考慮に入れるには、4台のホストが必要です。
推奨: vSANクラスターの場合、可用性を確保するには少なくとも4台のホストが必要です。
ただし、2台のホストと1台のリモート監視VMを想定したリモートオフィスブランチオフィス(ROBO)構成のような例外もあります。
イレイジャーコーディング
vSANのデフォルトのストレージ方式はRAID-1-データレプリケーションまたはミラーリングです。 イレイジャーコーディングは、ストレージオブジェクト/コンポーネントがクラスター内のストレージノードに分散されるRAID-5またはRAID-6です。 イレイジャーコーディングの主なメリットは、データ保護レベルを維持したまま容量効率を上げられることです。
前のセクションのFTTの計算を例として使用します。VMが2つの障害を許容する場合、RAID-1を使用するに、ストレージオブジェクトのコピーが3つ必要です。つまり、VMDKはベースVMDKのサイズの300%を消費します。 RAID-6ではVMが2つの障害に耐えることができ、VMDKのサイズの150%しか消費しません。
ここでは、パフォーマンスと容量のどちらかを選択する必要があります。 容量を節約できるのは素晴らしいことですが、イレイジャーコーディングを有効にする前にデータベースのIOパターンを考慮する必要があります。 容量効率が向上する代わりに、I/O処理が増加することになります。コンポーネントの障害が発生している間はさらに負荷が高くなるため、最高のデータベースパフォーマンスを確保するにはRAID-1を使用してください。
推奨: 本番データベースではイレイジャーコーディングを有効にしないでください。 本番環境以外で有効にしてください。
イレージャーコーディングはクラスターの必要なホスト数にも影響します。 例えばRAID-5の場合はクラスター内に最低4台のノードが必要で、RAID-6の場合は最低6台のノードが必要です。
推奨: イレイジャーコーディングの構成を計画する前に、追加ホストのコストを検討してください。
ストライピング
ストライピングはパフォーマンスを向上させるのに役立ちますが、役に立ちそうなのはハイブリッド構成だけだと思われます。
推奨: 本番データベースではストライピングを有効にしないでください。
オブジェクトスペースの予約(シンまたはシックプロビジョニング)
この設定の名前は、オブジェクトを使用してVM(VMDKなど)のコンポーネントを格納するvSANに由来しています。 デフォルトでは、VSANデータストアにプロビジョニングされるすべてのVMのオブジェクトスペースの予約は0%(シンプロビジョニング)になっています。この設定は容量を節約し、vSANのデータをより自由に配置できるようにします。 ただし、本番データベースでは予約値に100%(シックプロビジョニング)を使用し、作成時に容量を割り当てるのが最適です。 vSANの場合は、各ブロックへ初めて書き込まれるときに0が書き込まれるLazy Zeroedになります。 本番データベースの予約値に100%を選択する理由としては、データベースが拡張される際の遅延が少なくなり、必要なときにストレージを使用できることが保証されることが挙げられます。
推奨: 本番データベースのディスクの予約値には100%を使用してください。
推奨: 本番以外のインスタンスの場合、ストレージはシンプロビジョニングのままにしてください。
それぞれの機能をいつ有効化すべきですか?
通常はシステムをしばらく使用した後(システム上にアクティブなVMとユーザーが存在する状態)に可用性と容量節約の機能を有効化できます。 ただし、パフォーマンスと容量に影響します。 元のデータに加えてデータの複製が必要になるため、データを同期中は追加の容量が必要になります。 経験上、大規模なデータベースを使用するクラスターでこの種の機能を有効にすると、処理時間が非常に長くなり、可用性が低下する可能性があります。
推奨: 本番稼働を開始する前に、そして大規模なデータベースを読み込む前には必ず、事前に時間をかけて重複排除や圧縮などのストレージの機能を理解して構成するようにしてください。
ディスクバランシングや障害発生時用の空き領域を残すなど、他にも考慮事項があります。 つまり、この記事の推奨事項とベンダー固有の選択肢を考慮して物理ディスクの要件を把握する必要があります。
推奨: 多くの機能と置き換え可能な要素があります。 まずは合計GB容量の要件を見積もり、この記事の推奨事項を(アプリケーションベンダーと一緒に)確認してからHCIベンダーに相談してください。
ストレージ処理のオーバーヘッド
ホスト上でのストレージ処理のオーバーヘッドを考慮する必要があります。 かつてはエンタープライズストレージアレイのプロセッサが処理していたストレージの処理が、クラスター内の各ホストで実行されるようになっています。
各ホストのオーバーヘッドの大きさは、ワークロードと有効になっているストレージの機能によって決まります。 vSAN上のCachéで行ったテストの結果を見る限り、特に現在のサーバーで使用可能なコアの数を考慮すると、過度な処理要件はないと言えます。 VMwareはホストのCPU使用率が5〜10%になるよう計画することを推奨しています。
上記はサイジングを行う際にまず考慮すべき内容ですが、何が最適なのかは状況によって異なるため、確認が必要です。
推奨: CPU使用率が10%となる最悪のケースを想定し、実際のワークロードを監視してください。
ネットワーク
ベンダーの要件を確認してください。最小10GbEのNICを採用し、ストレージトラフィックや管理(例: vMotion)などに複数のNICを使うことを想定してください。 私は自分の苦い経験から、クラスターの最適な運用にはエンタープライズクラスのネットワークスイッチが必要であることを皆さんに伝えることができます。結局、可用性を確保するためにどんな書き込みもネットワーク経由で同期的に送信されるからです。
推奨: ストレージトラフィック用に最低10GbEの帯域幅を持つネットワークスイッチを使用してください。 ベストプラクティスに従い、ホストごとに複数のNICを用意してください。
フラッシュストレージの概要
HCIにはフラッシュストレージが必須であるため、フラッシュストレージの現状と今後の展望を確認することをお勧めします。
HCIを使用するかどうかにかかわらず、現時点でフラッシュを搭載したストレージを使用してアプリケーションを導入していないのであれば、次に購入するストレージにはフラッシュが搭載されている可能性があります。
ストレージの現状と未来
一般的に導入されているストレージソリューションの機能を確認し、用語を明確にしましょう。
回転式ディスク
昔ながらの SASまたはSATAインターフェースを備えた7,200回転、10,000回転、または15,000回転の回転式物理ディスクです。 ディスクあたりのIOPSは低いです。 このディスクは大容量にできますが、GBあたりのIOPSは減少します。 パフォーマンスを確保するため、通常は複数のディスクにデータを分散して「十分な」IOPSと大容量を実現します。
SSDディスク - SATAおよびSAS
現在、フラッシュは一般的にNANDフラッシュを使用する、SASまたはSATAインターフェースを持つSSDとして導入されています。 また、SSDにはいくらかのDRAMが書き込み可能なバッファメモリとして搭載されています。 エンタープライズSSDには停電保護機能が搭載されており、停電時にはDRAMの内容がNANDに書き込まれます。
SSDディスク - NVMe
SSDディスクと同様ですが、NVMeプロトコル(SASまたはSATAではない)とNANDフラッシュを使用します。 NVMeメディアはPCI Express(PCIe)バス経由で接続されるため、システムはホストバスアダプターやストレージファブリックのオーバーヘッドなしで直接通信でき、レイテンシが大幅に短縮されます。
ストレージアレイ
エンタープライズアレイは保護機能と拡張機能を提供します。 現在、ストレージの構成はハイブリッドアレイまたはオールフラッシュが一般的です。 ハイブリッドアレイにはNANDフラッシュのキャッシュ層のほか、7,200回転、10,000回転、または15,000回転の回転式ディスクを使用する1つ以上のキャパシティ層が含まれています。 NVMeアレイも利用できるようになっています。
ブロックモードNVDIMM
このデバイスは出荷が始まったばかりであり、非常に低いレイテンシが必要な場合に使用されます。 NVDIMMはDDRメモリソケットに装着され、レイテンシは約30ナノ秒です。 現在は8GBモジュールで出荷されているため、レガシーなデータベースアプリケーションには使用されない可能性が高いですが、新しいスケールアウトアプリケーションではこのパフォーマンスを利用できます。
3D XPoint
これは未来の技術であり、2016年11月時点では利用できません。
MicronおよびIntelによって開発されました。 また、Optane(Intel)およびQuantX(Micron)としても知られています。
少なくとも2017年までは利用できませんが、NANDと比較して容量が大きく、IOPSが10倍以上、レイテンシが10倍以上低くなるため、非常に高い耐久性と一貫したパフォーマンスが約束されます。
最初はNVMeプロトコルが採用される予定です。
SSDデバイスの耐久性
キャッシュ層とキャパシティ層のドライブを選択する際は、SSDデバイスの耐久性を考慮することが重要です。 フラッシュストレージの寿命は有限です。 SSDフラッシュのセルは、決まった回数だけ削除および再書き込みできます(読み取りに関しては制限はありません)。 デバイスのファームウェアはSSDの寿命を最大化するため、ドライブ全体に書き込みを分散するように調整します。 また、エンタープライズSSDは通常見た目よりも実際にはフラッシュの容量が大きいため(オーバープロビジョニング)、800 GBのドライブには1 TBを超えるフラッシュが搭載されている場合があります。
ストレージベンダーと話し合うために注目すべき指標は、一定年数で保証されている1日あたりのドライブ全体の書き換え可能回数(Drive Writes Per Day, DWPD)です。 例えば、1 DWPD(5年対応)の800 GB SSDは、1日に800 GBを5年間書き込むことができます。 したがって、DWPD(および年数)が多いほど耐久性が高くなります。 測定基準の計算方法を変え、指定されたSSDデバイスをテラバイト書き込み量(Terabytes Written, TBW)で表すこともできます。同じ例のTBWは、1,460 TB(800GB * 365日 * 5年)です。 どちらの方法でも、予想されるIOに基づいてSSDの寿命を知ることができます。
要約
この記事では、HCI、特にVMWare vSANバージョン6.5を導入する際に考慮すべき最も重要な機能について説明しました。 説明していないvSANの機能もあります。ここで言及していない機能については、デフォルト値を使用すべきだと考えてください。 ただし、ご質問やご意見がありましたら、コメントセクションで回答いたします。
今後の投稿ではHCIに戻る予定です。HCIは確実に発展していくアーキテクチャであるため、HCIに導入するインターシステムズのお客様が増えることを期待しています。
お知らせ
Mihoko Iijima · 2021年6月1日
開発者の皆さん、こんにちは!
いよいよ、第12回 InterSystems IRIS プログラミングコンテスト(FHIR Accelerator)の投票が、6月3日(木)US時間 から開始されます!
当初、5月31日(US時間)から投票開始予定でしたが、応募期間を延長し 6月3日が投票開始日となりました。
テーマは、InterSystems IRIS FHIR Accelerator Service (FHIRaaS) on AWS を使用して構築されたソリューションです。関連記事にご利用を開始するための手順を掲載しています。ぜひご参照ください。
➡️ 投票は 6月3日から! これだ 🔥 と思う作品への投票、よろしくお願いします!
投票方法や新機能について:
Experts nomination:
今回は、経験豊富な審査員がベストアプリを選び、Expert Nominationで賞品をノミネートします。
↓審査員↓
⭐️ @Regilo Souza, InterSystems Service Executive⭐️ @Anton Umnikov, InterSystems Senior Cloud Solution Architect⭐️ @Patrick Jamieson, InterSystems Product Manager - Health Informatics Platform⭐️ @Evgeny Shvarov, InterSystems Developer Ecosystem Manager
Community nomination:
開発者コミュニティのメンバーは、お好みのアプリケーションに対して1位~3位を指定しながら投票できます。
開発者コミュニティでのあなたの状態
順位
1位
2位
3位
開発者コミュニティに記事を掲載したり、OpenExchange(OEX)にアプリをアップロードしたことがある方
9点
6点
3点
開発者コミュニティに1つの記事を掲載した、または 1アプリケーションを OEX にアップロードしたことがある方
6点
4点
2点
開発者コミュニティへコメントや質問を投稿したことがある方
3点
2点
1点
エキスパートレベル
順位
1位
2位
3位
グローバルマスターズの VIP レベル または、InterSystems Product Managers
15点
10点
5点
グローバルマスターズの Ambassador レベル
12点
8点
4点
グローバルマスターズの Expert レベル または DC モデレーター
9点
6点
3点
グローバルマスターズの Specialist レベル
6点
4点
2点
グローバルマスターズの Advocate レベル または インターシステムズの従業員
3点
2点
1点
投票方法についての変更点は以下の通りです
今回のコンテストでは、現時点の投票数を隠す「ブラインド投票」を行うことにしました。
そのため、アプリケーションへの投票数は 1日1回、この投稿のコメント欄に公開予定です。
メモ:新しいコメントの通知を受けるために、この投稿を購読することをお忘れなく!(記事末尾の ベルのアイコンをクリックするだけ!)
コンテストページの応募作品表示順については、コンテストに応募した時期が早ければ早いほど、上位に表示されます。
投票に参加するには?
Open Exchange へのサインインします(開発者コミュニティのアカウントを使用してください)。
投票ボタンは、開発者コミュニティ内で、質問/回答/記事の掲載/投稿に対するコメント など 記載いただいた方に対して有効になります。 ボタンが押せない場合は、コミュニティへのコメントやオリジナルの記事など、書き込みお願いします!詳細は、こちらの記事をご参照ください。
気が変わった場合は? - 選択をキャンセルして別のアプリケーションに投票できます。
世界の IRIS 開発者が作成した ✨素敵なアプリ✨ が公開されています!ぜひ 🔥これだ🔥 と思う作品に投票お願いします!
メモ:コンテストへ応募された作品は、投票週間中にバグを修正したり、アプリケーションを改良したりすることができますので、アプリケーションのリリースを見逃さずに購読してください。
記事
Toshihiko Minamoto · 2021年7月19日
はじめに
近年、オープン認証フレームワーク(OAuth)を使って、あらゆる種類のサービスから信頼性のある方法で安全かつ効率的にリソースにアクセスするアプリケーションが増えています。 InterSystems IRIS はすでに OAuth 2.0 フレームワークに対応しており、事実コミュニティには、OAuth 2.0 と InterSystems IRIS に関する素晴らしい[記事](https://community.intersystems.com/post/intersystems-iris-open-authorization-framework-oauth-20-implementation-part-1)が掲載されています。
しかし、API 管理ツールの出現により、一部の組織はそのツールを単一の認証ポイントとして使用し、不正なリクエストが下流のサービスに到達するのを防ぎ、サービスそのものから承認/認証の複雑さを取り除いています。
ご存知かもしれませんが、InterSystems は、IRIS Enterprise ライセンス(IRIS Community Edition ではありません)で利用できる InterSystems API Management(IAM)という API 管理ツールを公開しています。 [こちら](https://community.intersystems.com/post/introducing-intersystems-api-manager)には、InterSystems API Management を紹介する素晴らしい別のコミュニティ記事が掲載されています。
これは、IAM を使って、以前に IRIS にデプロイされた認証されていないサービスに OAuth 2.0 標準に従ったセキュリティを追加する方法を説明した 3 部構成記事の最初の記事です。
サービスを保護するプロセス全体を理解しやすくするために、最初の記事では、IRIS と IAM の基本的な定義と構成を示しながら OAuth 2.0 の背景を説明します。
この連載記事のパート 2 以降では、IAM によってサービスを保護する上で考えられる 2 つのシナリオを説明します。 最初のシナリオでは、IAM は着信リクエストに存在するアクセストークンを検証し、検証が成功した場合にのみリクエストを 転送します。 2 番目のシナリオでは、IAM がアクセストークンを生成し(承認サーバーとして機能します)、それを検証します。
従って、パート 2 では、シナリオ 1 を構成するために必要な手順を詳しく説明し、パート 3 ではシナリオ 2 の構成を説明した上で、最終的な考慮事項を示します。
IAM をお試しになりたい方は、InterSystems 営業担当者にお問い合わせください。
OAuth 2.0 の背景
すべての OAuth 2.0 承認フローには基本的に以下の 4 つのグループが関わっています。
1. ユーザー
2. クライアント
3. 承認サーバー
4. リソース所有者
分かりやすくするために、この記事では「リソース所有者パスワード資格情報」OAuth フローを使用しますが、IAM ではあらゆる OAuth フローを使用できます。 また、この記事では範囲を指定しません。
注意: クライアントアプリはユーザー資格情報を直接処理するため、クライアントアプリの信頼性が非常に高い場合にのみリソース所有者パスワード資格情報フローを使用することをお勧めします。 ほとんどの場合、クライアントはファーストパーティアプリである必要があります。
以下は、一般的なリソース所有者パスワード資格情報フローの手順です。
1. ユーザーはクライアントアプリに資格情報(ユーザー名とパスワードなど)を入力します。
2. クライアントアプリは承認サーバーにユーザー資格情報と独自の ID(クライアント ID とクライアントシークレットなど)を送信します。 承認サーバーはユーザー資格情報とクライアント ID を検証し、アクセストークンを返します。
3. クライアントはトークンを使用して、リソースサーバーにあるリソースにアクセスします。
4. リソースサーバーは受け取ったアクセストークンを検証してから、クライアントに情報を返します。
これを踏まえ、IAM を使用して OAuth 2.0 を処理できるシナリオが 2 つあります。
1. IAM はバリデーターをして機能し、クライアントアプリが提供するアクセストークンを検証し、アクセストークンが有効である場合にのみリソースサーバーにリクエストを転送します。この場合、アクセストークンはサードパーティの承認サーバーによって生成されます。
2. IAM は承認サーバーとしてクライアントにアクセストークンを提供し、アクセストークンのバリデーターとしてアクセストークンを検証してから、リソースサーバーにリクエストをリダイレクトします。
IRIS と IAM の定義
この記事では、「/SampleService」という IRIS Web アプリケーションを使用します。 以下のスクリーンショットからわかるように、これは IRIS にデプロイされた認証されていない REST サービスです。
さらに、以下のスクリーンショットのとおり、IAM 側では 1 つのルートを含む「SampleIRISService」というサービスが構成されています。
また、IAM では、IAM で API を呼び出しているユーザーを識別するために、最初に資格情報の無い「CliantApp」というコンシューマーが構成されています。
上記の構成により、IAM は次の URL に送信されるすべての GET リクエストを IRIS にプロキシしています。
**http://iamhost:8000/event**
この時点では、認証は使用されていません。 したがって、認証無しで単純な GET リクエストを次の URL に送信する場合、
**http://iamhost:8000/event/1**
必要なレスポンスを得られます。
この記事では、「PostMan」というアプリを使用してリクエストを送信し、レスポンスを確認します。 以下の PostMan のスクリーンショットでは、単純な GET リクエストとそのレスポンスを確認できます。
着信リクエストに存在するアクセストークンを検証するように IAM を構成する方法を理解するには、この連載のパート 2 をお読みください。
記事
Mihoko Iijima · 2021年8月23日
これは InterSystems FAQ サイトの記事です。
InterSystems IRIS Business Intelligence 用メニューの Analytics(または DeepSee)を使用するためには、使用するネームスペース用ウェブアプリケーションパスを Analytics(またはDeepSee)に対応するように設定変更する必要があります。
詳細については以下のドキュメントをご参照ください。
【IRIS】InterSystems IRIS Business Intelligence の Web アプリケーション設定について
【2015.1~2018.1】DeepSee の Web アプリケーション設定について
【~2014.1】%CSPページへのアプリケーション・アクセスの制御について/特殊なケース: DeepSee
関連する FAQ トピックもご参照ください。
% 付き Web ページを開くとエラーになります。
お知らせ
Toshihiko Minamoto · 2022年6月4日
インターシステムズは InterSystems IRIS Data Platform、InterSystems IRIS for Health、 HealthShare Health Connect がリリースされたことをお知らせします。
2022.1は、EMリリースですので、メンテナンス・ビルドが2年間利用でき、その後、さらに2年間、セキュリティに特化したビルドが利用できるようになります。
本リリースのハイライト
プラットホームの更新
InterSystems IRIS Data Platform 2022.1 は以下の最新OSをサポートします。
Windows Server 2022
Windows 11
AIX 7.3
Oracle Linux 8
また、開発環境用として、M1 ならびに IntelチップセットのMacOS 12 (Monterey) をサポートします。
開発環境の向上
Embedded Python ... IRIS内でObjectScriptとPythonが使用できます。
Kafka,やAWS S3、AWS SNS、CloudWatch向けアダプタの追加
Production Extensions (PEX)のユーザインターフェースの更新
スピード、スケール、セキュリティ, Scale, & Security
オンライン・シャード・リバランシング
アダプティブ SQL
ジャーナル、ストリーム圧縮
メールでのTLS 1.3, OAuth 2 サポート
アナリティクス AI
SQL ローダー
InterSystems Reports デプロイメントの改良
これらの機能の詳細は製品ドキュメントをご覧ください
InterSystems IRIS 2022.1 ドキュメント and リリースノート
InterSystems IRIS for Health 2022.1 ドキュメント and リリースノート
HealthShare Health Connect 2022.1 ドキュメント and リリースノート
ソフトウェアの取得方法
このソフトウェアは従来のインストレーションパッケージとコンテナイメージの両方で取得できます。使用可能なインストレーションパッケージとコンテナイメージの全リストはSupported Platforms documentをご参照ください。
各製品の完全なインストレーションパッケージはWRCの Software Distribution page より取得できます。 カスタムインストレーションオプションを使用するとスタジオやIntegratedMLなど、必要なオプションを選択でき、インストールのフットプリントを適正なサイズにできます。
InterSystems IRIS and IRIS for Healthの Enterprise Edition、関連するコンポーネントのコンテナイメージは InterSystems Container Registry から以下のコマンドを使用して入手できます。
docker pull containers.intersystems.com/intersystems/iris:2022.1.0.209.0
docker pull containers.intersystems.com/intersystems/irishealth:2022.1.0.209.0
docker pull containers.intersystems.com/intersystems/iris-arm64:2022.1.0.209.0
docker pull containers.intersystems.com/intersystems/irishealth-arm64:2022.1.0.209.0
docker pull containers.intersystems.com/intersystems/iris-ml:2022.1.0.209.0
docker pull containers.intersystems.com/intersystems/iris-ml-arm64:2022.1.0.209.0
利用可能なコンテナイメージのリストは ICR documentation をご覧ください。
Community Edition のコンテナイメージもInterSystems Container Registryから以下のコマンドで入手可能です。
docker pull containers.intersystems.com/intersystems/iris-community:2022.1.0.209.0
docker pull containers.intersystems.com/intersystems/irishealth-community:2022.1.0.209.0
docker pull containers.intersystems.com/intersystems/iris-community-arm64:2022.1.0.209.0
docker pull containers.intersystems.com/intersystems/irishealth-community-arm64:2022.1.0.209.0
docker pull containers.intersystems.com/intersystems/iris-ml-community:2022.1.0.209.0
docker pull containers.intersystems.com/intersystems/iris-ml-community-arm64:2022.1.0.209.0
InterSystems IRIS Studio 2022.1 はマイクロソフト Windows で動作する統合開発環境のコンポーネントで、WRCのコンポーネントダウンロードページ からダウンロードできます。 これはInterSystems IRIS and IRIS for Health version 2022.1 以下の環境で動作します。また、インターシステムズはマイクロソフトWindowsやLinux、MacOSで利用可能なVisual Studio Codeを使ってInterSystems IRISのアプリケーションを開発するためのVSCode-ObjectScript plugin をサポートします。
主なクラウドマーケットプレイスにおける弊社の対応リストは、数日中に更新される予定です。
このリリース版のビルド番号は、2022.1.0.209.0 です。
記事
Shintaro Kaminaka · 2020年7月3日
この記事と後続の2つの連載記事は、InterSystems製品ベースのアプリケーションでOAuth 2.0フレームワーク(簡略化のためにOAUTHとも呼ばれます)を使用する必要のある開発者またはシステム管理者向けのユーザーガイドを対象としています。
作成者:Daniel Kutac(InterSystemsシニアセールスエンジニア)
公開後の修正および変更の履歴
2016年8月3日 - 新しいバージョンのページを反映するため、Googleのクライアント設定のスクリーンショットを修正し、Google APIのスクリーンショットを更新しました。
2016年8月28日 - Cache 2016.2でのJSON対応への変更を反映するため、JSON関連コードを変更しました。
2017年5月3日 - Cache 2017.1でリリースされた新しいUIと機能を反映するため、テキストと画面を更新しました。
2018年2月19日 - 最新の開発内容を反映するために、CachéをInterSystems IRISに変更しました。 製品名は変更されていますが、この記事はすべてのInterSystems製品(InterSystems IRIS Data Platform、Ensemble、Caché)を対象としています。
パート1. クライアント
概要
これは、3部構成のInterSystemsによるOpen Authorization Frameworkの実装に関する連載記事の最初の記事です。
この最初のパートでは、このトピックについて簡単に紹介し、InterSystems IRISアプリケーションが認証サーバーのクライアントとして機能し、保護されたリソースを要求する簡単なシナリオを示します。
パート2ではより複雑なシナリオについて説明します。そこではInterSystems IRIS自体が認証サーバーとして機能するほか、OpenID Connectを介した認証サーバーとしても機能します。
このシリーズの最後のパートでは、OAUTHフレームワーククラスの個々の部分について説明します。それらはInterSystems IRISにより実装されているからです。
Open Authorization Framework[1]とは
皆さんの多くはすでにOpen Authorization Frameworkとその使用目的について聞いたことがあるかと思います。 そのため、この記事では初めて同フレームワークを耳にした方のために簡単な要約を掲載します。
現在はバージョン2.0であるOpen Authorization Framework(OAUTH)は、クライアント(データを要求するアプリケーション)とリソース所有者(要求されたデータを保持するアプリケーション)の間に間接的な信頼を確立することにより、主にWebベースのアプリケーションが安全な方法で情報を交換できるようにするプロトコルです。 この信頼自体は、クライアントとリソースサーバーの両方が認識して信頼する機関によって提供されます。 この機関は認証サーバーと呼ばれます。
次の事例を使用して簡単に説明します。
Jenny(OAUTH用語ではリソース所有者)がJennyCorp社のプロジェクトに取り組んでいるとします。 彼女はより大きな潜在的なビジネスのプロジェクト計画を作成し、JohnInc社のビジネスパートナーであるJohn(クライアントユーザー)にドキュメントのレビューを依頼します。 ただし、彼女はジョンに自社のVPNへのアクセスを許可することを快く思っていないので、ドキュメントをGoogleドライブ(リソースサーバー)または他の同様のクラウドストレージに置いています。 そうすることで、彼女は彼女とGoogle(認証サーバー)の間に信頼関係を確立していました。 彼女はJohnと共有するドキュメントを選びます(JohnはすでにGoogleドライブを使用しており、Jennyは彼のメールアドレスを知っています)。
Johnはドキュメントを閲覧したいときには自分のGoogleアカウントで認証し、モバイルデバイス(タブレットやノートパソコンなど)からドキュメントエディタ(クライアントサーバー)を起動し、Jennyのプロジェクトファイルを読み込みます。
とてもシンプルに聞こえますが、2人とGoogleの間には多くの通信が発生しています。 どの通信もOAuth 2.0仕様に準拠しているため、Johnのクライアント(リーダーアプリケーション)は最初にGoogleで認証する必要があります(OAUTHはこのステップに対応していません)。ジョンがGoogleが提供するフォームにJohnが同意して認証すると、Googleはアクセストークンを発行し、リーダーアプリケーションにドキュメントへのアクセスを許可します。 リーダーアプリケーションはアクセストークンを使用してGoogleドライブにリクエストを発行し、Jennyのファイルを取得します。
以下の図に、個々の当事者間の通信を示しています。
注意: どのOAUTH 2.0通信もHTTPリクエストを使用していますが、サーバーは必ずしもWebアプリケーションである必要はありません。
InterSystems IRISを使ってこの簡単なシナリオを説明しましょう。
簡単なGoogleドライブのデモ
このデモでは、私たち自身のアカウントを使ってGoogleドライブに保存されているリソース(ファイルのリスト)をリクエストする小さなCSPベースのアプリケーションを作成します(ついでにカレンダーのリストも取得します)。
前提条件
アプリケーションのコーディングを始める前に、環境を準備する必要があります。 この環境には、SSLが有効になっているWebサーバーとGoogleのプロファイルが含まれます。
Webサーバーの構成
上記のように、認証サーバーとはSSLを使用して通信する必要があります。これは、OAuth 2.0がデフォルトでSSLを要求するためです。 データを安全に保つためには必要なことですよね?
この記事ではSSLをサポートするようにWebサーバーを構成する方法は説明しませんので、お好みの各Webサーバーのユーザーマニュアルを参照してください。 皆さんの好奇心をそそるため、この詳細な例ではMicrosoft IISサーバーを使用します(後でいくつかのスクリーンショットを掲載するかもしれません)。
Googleの構成
Googleに登録するには、Google API Manager(https://console.developers.google.com/apis/library?project=globalsummit2016demo)を使用する必要があります
デモのために、GlobalSummit2016Demoというアカウントを作成しました。 Drive APIが有効になっていることを確認してください。
次に、認証情報を定義します。
次の点に注意してください。
承認済みのJavaScript生成元 – 呼び出し元のページに対し、ローカルで作成されたスクリプトのみを許可します。
承認済みのリダイレクトURI – 理論上はクライアントアプリケーションを任意のサイトにリダイレクトできますが、InterSystems IRISのOAUTH実装を使用する場合は https://localhost/csp/sys/oauth2/OAuth2.Response.cls にリダイレクトする必要があります。 スクリーンショットのように複数の承認済みのリダイレクトURIを定義できますが、このデモでは2つのうち2番目のエントリのみが必要です。
最後に、InterSystems IRISをGoogle認証サーバーのクライアントとして構成する必要があります。
Cachéの構成
InterSystems IRIS OAUTH2クライアントの構成は2段階で行われます。 まず、サーバー構成を作成する必要があります。
SMPで、System Administration(システム管理) > Security(セキュリティ) > OAuth 2.0 > Client Configurations(クライアント構成)を開きます。
「サーバー構成の作成」ボタンをクリックし、フォームに入力して保存します。
フォームに入力したすべての情報は、Google Developers Consoleのサイトで確認できます。 InterSystems IRISはOpen IDの自動検出に対応しています。 ただし、ここでは自動検出を使用せず、すべての情報を手動で入力しました。
次に、新しく作成された発行者エンドポイントの横にある「Client Configurations」(クライアント構成)リンクをクリックし、「Create Client Configuration」(クライアント構成を作成する)ボタンをクリックします。
「Client Information」(クライアント情報)タブと「JWT Settings」(JWT設定)タブは空のままにし(デフォルト値を使用します)、クライアントの認証情報を入力してください。
注意:ここでは、Confidential Clientを作成しています。これはPublic Clientよりも安全であり、クライアントシークレットがクライアントサーバーアプリケーションを離れることはありません(ブラウザに送信されません)。
また、「Use SSL/TLS」(SSL/TLSを使用する)がチェックされ、ホスト名(ここではクライアントアプリケーションにローカルにリダイレクトしているため、localhostにします)が入力され、さらにはポートとプレフィックスが入力されていることを確認してください(これは同じマシンに複数のInterSystems IRISがある場合に役立ちます)。 入力した情報に基づいてクライアントリダイレクトURLが生成され、上の行に表示されます。
上のスクリーンショットでは、GOOGLEという名前のSSL構成を選択しました。 この名前自体は、多くのSSL構成のうちどれをこの特定の通信チャネルで使用するかを決定するためにのみ使用されます。 CachéはSSL/TLS構成を使用し、サーバー(この場合はGoogle OAuth 2.0 URI)との安全なトラフィックを確立するために必要なすべての情報を保存しています。
より詳細な説明については、ドキュメントを参照してください。
Googleの認証情報定義フォームから取得したクライアントIDとクライアントシークレットの値を入力します(手動構成を使用する場合)。
これですべての構成ステップが完了し、CSPアプリケーションのコーディングに進むことができます。
クライアントアプリケーション
クライアントアプリケーションは、シンプルなWebベースのCSPアプリケーションです。 そのため、Webサーバーによって定義および実行されるサーバー側のソースコードと、Webブラウザによってユーザーに公開されるユーザーインターフェイスで構成されています。
クライアントサーバー
クライアントサーバーは単純な2ページのアプリケーションです。 アプリケーション内では次の処理を実行します。
· Google認証サーバーのリダイレクトURLを組み立てます。
· Google Drive APIおよびGoogle Calendar APIへのリクエストを実行し、結果を表示します。
ページ1
これはアプリケーションの1ページであり、そのリソースについてGoogleを呼び出すことにしました。
以下はこのページを表す最小限の、しかし完全に動作するコードです。
Class Web.OAUTH2.Google1N Extends %CSP.Page
{
Parameter OAUTH2CLIENTREDIRECTURI = "https://localhost/csp/google/Web.OAUTH2.Google2N.cls";
Parameter OAUTH2APPNAME = "Google";
ClassMethod OnPage() As %Status
{
&html<<html>
<head>
</head>
<body style="text-align: center;">
<!-- ページの内容をここに挿入します -->
<h1>Google OAuth2 API</h1>
<p>このページのデモでは、OAuth2認証を使用してGoogle API関数を呼び出す方法を示しています。
<p>ユーザーとユーザーのGoogleドライブのファイル、およびカレンダーエントリに関する情報を取得します。
>
// Googleで認証するにはopenidのスコープを指定する必要があります
set scope="openid https://www.googleapis.com/auth/userinfo.email "_
"https://www.googleapis.com/auth/userinfo.profile "_
"https://www.googleapis.com/auth/drive.metadata.readonly "_
"https://www.googleapis.com/auth/calendar.readonly"
set properties("approval_prompt")="force"
set properties("include_granted_scopes")="true"
set url=##class(%SYS.OAuth2.Authorization).GetAuthorizationCodeEndpoint(..#OAUTH2APPNAME,scope,
..#OAUTH2CLIENTREDIRECTURI,.properties,.isAuthorized,.sc)
w !,"<p><a href='"_url_"'><img border='0' alt='Googleサインイン' src='images/google-signin-button.png' ></a>"
&html<</body>
</html>>
Quit $$$OK
}
ClassMethod OnPreHTTP() As %Boolean [ ServerOnly = 1 ]
{
#dim %response as %CSP.Response
set scope="openid https://www.googleapis.com/auth/userinfo.email "_
"https://www.googleapis.com/auth/userinfo.profile "_
"https://www.googleapis.com/auth/drive.metadata.readonly "_
"https://www.googleapis.com/auth/calendar.readonly"
if ##class(%SYS.OAuth2.AccessToken).IsAuthorized(..#OAUTH2APPNAME,,scope,.accessToken,.idtoken,.responseProperties,.error) {
set %response.ServerSideRedirect="Web.OAUTH2.Google2N.cls"
}
quit 1
}
}
以下にこのコードの簡単な説明を記します。
1. OnPreHTTPメソッド - まず、すでに有効なアクセストークンをGoogleの認証結果として取得しているかどうかを確認します。この認証は、例えば単にページを更新したときに発生する可能性があります。 トークンを取得できていない場合は、認証する必要があります。 トークンを取得できている場合は、結果表示ページにページをリダイレクトするだけです。
2. OnPageメソッド - 有効なアクセストークンがない場合にのみここに到達します。その場合、認証してGoogleに対する権限を付与し、アクセストークンを付与してもらうために通信を開始しなければなりません。
3. Google認証ダイアログの動作を変更するスコープ文字列とプロパティ配列を定義します(私たちのIDに基づいて認証する前に、Googleに対して認証する必要があります)。
4. 最後にGoogleのログインページのURLを受け取り、それをユーザーに提示してから同意ページを表示します。
追加の注意事項:
ここでは実際のリダイレクトページを https://www.localhost/csp/google/Web.OAUTH2.Google2N.cls(OAUTH2CLIENTREDIRECTURIパラメータ内)で指定しています。 ただし、Google認証情報の定義ではInterSystems IRIS OAUTH Frameworkのシステムページを使用しています。 リダイレクトは、OAUTHハンドラークラスによって内部的に処理されます。
ページ2
このページにはGoogle認証の結果が表示されます。成功した場合はGoogleのAPIコールを呼び出してデータを取得します。 繰り返しになりますが、このコードは最小限でも完全に機能します。 受信データがどのような構造で表示されるかは、皆さんのご想像にお任せします。
Include %occInclude
Class Web.OAUTH2.Google2N Extends %CSP.ページ
{
Parameter OAUTH2APPNAME = "Google";
Parameter OAUTH2ROOT = "https://www.googleapis.com";
ClassMethod OnPage() As %Status
{
&html<<html>
<head>
</head>
<body>>
// アクセストークンがあるかどうかを確認します
set scope="openid https://www.googleapis.com/auth/userinfo.email "_
"https://www.googleapis.com/auth/userinfo.profile "_
"https://www.googleapis.com/auth/drive.metadata.readonly "_
"https://www.googleapis.com/auth/calendar.readonly"
set isAuthorized=##class(%SYS.OAuth2.AccessToken).IsAuthorized(..#OAUTH2APPNAME,,scope,.accessToken,.idtoken,.responseProperties,.error)
if isAuthorized {
// Googleにはイントロスペクションエンドポイントがありませんので、呼び出す必要はありません。イントロスペクションエンドポイントと表示結果については、RFC 7662を参照してください。
w "<h3><span style='color:red;'>GetUserInfo API</span>からのデータ</h3>"
// userinfoには専用のAPIがありますが、Get() メソッドを適切なURLで呼び出すだけでも取得できます。
try {
set tHttpRequest=##class(%Net.HttpRequest).%New()
$$$THROWONERROR(sc,##class(%SYS.OAuth2.AccessToken).AddAccessToken(tHttpRequest,"query","GOOGLE",..#OAUTH2APPNAME))
$$$THROWONERROR(sc,##class(%SYS.OAuth2.AccessToken).GetUserinfo(..#OAUTH2APPNAME,accessToken,,.jsonObject))
w jsonObject.%ToJSON()
} catch (e) {
w "<h3><span style='color: red;'>エラー: ",$zcvt(e.DisplayString(),"O","HTML")_"</span></h3>"
}
/******************************************
* *
* 他のAPIから情報を取得する *
* *
******************************************/
w "<hr>"
do ..RetrieveAPIInfo("/drive/v3/files")
do ..RetrieveAPIInfo("/calendar/v3/users/me/calendarList")
} else {
w "<h1>認証されていません!</h1>"
}
&html<</body>
</html>>
Quit $$$OK
}
ClassMethod RetrieveAPIInfo(api As %String)
{
w "<h3><span style='color:red;'>"_api_"</span>からのデータ</h3><p>"
try {
set tHttpRequest=##class(%Net.HttpRequest).%New()
$$$THROWONERROR(sc,##class(%SYS.OAuth2.AccessToken).AddAccessToken(tHttpRequest,"query","GOOGLE",..#OAUTH2APPNAME))
$$$THROWONERROR(sc,tHttpRequest.Get(..#OAUTH2ROOT_api))
set tHttpResponse=tHttpRequest.HttpResponse
s tJSONString=tHttpResponse.Data.Read()
if $e(tJSONString)'="{" {
// JSONではない
d tHttpResponse.OutputToDevice()
} else {
w tJSONString
w "<hr/>"
/*
// 新しいJSON API
&html<<table border=1 style='border-collapse: collapse'>>
s tJSONObject={}.%FromJSON(tJSONString)
set iterator=tJSONObject.%GetIterator()
while iterator.%GetNext(.key,.value) {
if $isobject(value) {
set iterator1=value.%GetIterator()
w "<tr><td>",key,"</td><td><table border=1 style='border-collapse: collapse'>"
while iterator1.%GetNext(.key1,.value1) {
if $isobject(value1) {
set iterator2=value1.%GetIterator()
w "<tr><td>",key1,"</td><td><table border=0 style='border-collapse: collapse'>"
while iterator2.%GetNext(.key2,.value2) {
write !, "<tr><td>",key2, "</td><td>",value2,"</td></tr>"
}
// このようにして埋め込みオブジェクト/配列をどんどん進めていきます
w "</table></td></tr>"
} else {
write !, "<tr><td>",key1, "</td><td>",value1,"</td></tr>"
}
}
w "</table></td></tr>"
} else {
write !, "<tr><td>",key, "</td><td>",value,"</td></tr>"
}
}
&html<</table><hr/>
>
*/
}
} catch (e) {
w "<h3><span style='color: red;'>エラー: ",$zcvt(e.DisplayString(),"O","HTML")_"</span></h3>"
}
}
}
コードを簡単に見てみましょう。
1. まず、有効なアクセストークンがあるかどうかを確認する必要があります(そのため、認証を受けました)。
2. トークンがある場合はGoogleが提供し、発行されたアクセストークンがカバーするAPIにリクエストを発行できます。
3. そのためには標準の %Net.HttpRequest クラスを使用しますが、呼び出されたAPIの仕様に従ってGETメソッドまたはPOSTメソッドにアクセストークンを追加します。
4. ご覧のように、OAUTHフレームワークには GetUserInfo() メソッドが実装されていますが、RetrieveAPIInfo() ヘルパーメソッドの場合と同様に、Google APIの仕様を利用して直接ユーザー情報を取得できます。
5. OAUTHの世界ではJSON形式でデータを交換するのが一般的であるため、ここでは受信データを読み取り、それを単にブラウザに出力してます。 受信データを解析して整形し、それをユーザーが理解できる形で表示できるようにするのはアプリケーション開発者の責任です。 しかし、それはこのデモの範囲を超えています。 (ただし、いくつかのコメントアウトされたコードで構文解析のやり方を示しています。)
以下は、未加工のJSONデータが表示された出力のスクリーンショットです。
パート2に進んでください。そこでは、認証サーバーおよびOpenID Connectプロバイダーとして機能するInterSystems IRISについて説明します。
[1] https://tools.ietf.org/html/rfc6749、https://tools.ietf.org/html/rfc6750
記事
Shintaro Kaminaka · 2020年8月26日
作成者:Daniel Kutac(InterSystems セールスエンジニア)
パート 3. 付録
## InterSystems IRIS OAUTH クラスの説明
この連載の[前のパート](https://jp.community.intersystems.com/node/480201)では、InterSystems IRIS を OAUTH クライアントおよび認可/認証サーバー(OpenID Connect を使用)として機能するように構成する方法について学びました。 この連載の最後のパートでは、InterSystems IRIS OAuth 2.0 フレームワークを実装するクラスについて説明します。 また、一部の API クラスのメソッドの使用例についても説明します。
OAuth 2.0 を実装する API クラスは、目的に応じて 3 種類のグループに分けることができます。 すべてのクラスは %SYS ネームスペースで実装されています。 これらの一部は(% package 経由で)公開されていますが、一部は非公開になっており、開発者が直接呼び出すことはできません。
### 内部クラス
これらのクラスは OAuth2 パッケージに属しています。
次の表に、対象となるクラスの一部を掲載しています(クラスの完全なリストについては、CachéあるいはIRIS インスタンスのオンラインクラスリファレンスを参照してください)。 以下の表に掲載されているものを除き、これらのクラスをアプリケーション開発者が直接使用することはできません。
クラス名
説明
OAuth2.AccessToken
Persistent(永続クラス)
OAuth2.AccessToken は、OAuth 2.0 アクセストークンとその関連情報を格納します。 これは、アクセストークンの OAUTH クライアントコピーです。OAuth2.AccessToken は、SessionId と ApplicationName の組み合わせによってインデックス化されます。 したがって、SessionId/ApplicationName ごとに 1 つのスコープのみをリクエストできます。 2 回目のリクエストが別のスコープで行われ、アクセストークンがまだ付与されている場合は、新しいリクエストのスコープが予期されるスコープになります。
OAuth2.Client
Persistent(永続クラス)
OAuth2.Application クラスは OAuth2 クライアントを記述し、RFC 6749 に基づいてアプリケーションを認可するために使用する認可サーバーを参照します。 クライアントシステムは、さまざまなアプリケーションで複数の認可サーバーと共に使用できます。
OAuth2.Response
CSPページ
これは、InterSystems IRIS OAuth 2.0 クライアントコードから使用される OAuth 2.0 認可サーバーからの応答用のランディングページです。 応答はここで処理され、最終的なターゲットにリダイレクトされます。
OAuth2.ServerDefinition
Persistent(永続クラス)
OAUTH クライアント(この InterSystems IRIS インスタンス)が使用する認可サーバーの情報が格納されています。 認可サーバーの定義ごとに複数のクライアント構成を定義できます。
OAuth2.Server.AccessToken
Persistent(永続クラス)
アクセストークンは OAUTH サーバーの OAuth2.Server.AccessToken によって管理されます。 このクラスには、アクセストークンと関連プロパティが格納されます。 このクラスは、認可サーバーのさまざまな要素間の通信手段でもあります。
OAuth2.Server.Auth
CSP ページ
認可サーバーは、RFC 6749 で指定されている認可コードおよびインプリシットグラントタイプの認可制御フローをサポートします。 OAuth2.Server.Auth クラスは認可エンドポイントとして機能し、RFC 6749 に従ってフローを制御する %CSP.Page のサブクラスです。
OAuth2.Server.Client
Persistent(永続クラス)
OAuth2.Server.Configuration は、この認可サーバーに登録したクライアントを記述する永続クラスです。
OAuth2.Server.Configuration
Persistent(永続クラス)
認可サーバーの構成が格納されます。 すべての構成クラスには、ユーザーが構成の詳細を入力するためのシステム管理ポータルページがそれぞれ存在します。
OAuth2.Client、OAuth2.ServerDefinition、OAuth2.Server.Client、OAuth2.Configuration の各オブジェクトは UI を使用せずに開き、変更し、作成または変更した構成を保存できます。 これらのクラスを使用し、構成をプログラムで操作できます。
### サーバーカスタマイズ用クラス
これらのクラスは %OAuth2 パッケージに属しています。 このパッケージには、一連の内部クラス(ユーティリティ)が含まれています。ここでは、開発者が使用できるクラスについてのみ説明します。 これらのクラスは、OAuth 2.0 Server Configuration(サーバー構成)ページで参照されます。
%OAuth2.Server.Authenticate
CSPページ
%OAuth2.Server.Authenticate はデフォルトの Authenticate クラスだけでなく、ユーザーが作成したすべての Authenticate クラスのサブクラスとして機能します。 Authenticate クラスは、ユーザーを認証するために OAuth2.Server.Auth の認可エンドポイントによって使用されます。 このクラスを使用すると、認証プロセスをカスタマイズできます。次のメソッドを OAuth2.Server のデフォルトをオーバーライドするために実装できます。
DirectLogin– ログインページを表示しない場合にのみ使用します。
DisplayLogin – 認可サーバーのログインフォームを実装します。
DisplayPermissions – リクエストされたスコープのリストを使用してフォームを実装します。CSS を変更することで、外観や操作性をさらにカスタマイズできます。 CSS スタイルは DrawStyle メソッドで定義されます。loginForm は DisplayLogin フォーム用です。permissionForm は DisplayPermissions フォーム用です。
%OAuth2.Server.Validate
CSP ページ
これは、サーバーに含まれているデフォルトの Validate User Class(ユーザー検証クラス)です。 デフォルトのクラスは、認証サーバーが配置されている Cache またはIRISインスタンスのユーザーデータベースを使用してユーザーを検証します。 サポートされるプロパティは、issuer(Issuer)、role、sub(Username)です。Validate User Class は Authorization Server Configuration(認可サーバーの構成)で指定されます。 ユーザー名とパスワードの組み合わせを検証し、ユーザーに関連付けられたプロパティ一式を返す ValidateUser メソッドを含める必要があります。
%OAuth2.Server.Generate
Registered Object(登録オブジェクト)
%OAuth2.Server.Generate は、サーバーに含まれているデフォルトのGenerate Token Class(トークン生成クラス)です。 デフォルトのクラスは、ランダムな文字列を opaque アクセストークンとして生成します。Generate Token Class は、Authorization Server Configuration で指定されます。 ValidateUser メソッドによって返されるプロパティの配列に基づいてアクセストークンを生成するために使用される GenerateAccessToken メソッドを含める必要があります。
%OAuth2.Server.JWT
Registered Object(登録オブジェクト)
%OAuth2.Server.JWT は、サーバーに含まれている JSON Web トークンを作成する Generate Token Class です。 Generate Token Class は、Authorization Server Configuration で指定されます。 ValidateUser メソッドによって返されるプロパティの配列に基づいてアクセストークンを生成するために使用される GenerateAccessToken メソッドを含める必要があります。
%OAuth2.Utils
Registered Object(登録オブジェクト)
このクラスは、さまざまなエンティティのログの記録を実装します。 カスタマイズの章のサンプルコードに、可能な使用法を示しています。
次の画像に、OAuth 2.0 認可サーバー構成の対応するセクションを示します。

OpenID Connect を JWT 形式の識別情報トークン(id_token)と共に使用する場合は、構成内のデフォルトの Generate Token Class である _%OAuth2.Server.Generate_ を _%OAuth2.Server.JWT_ に置換してください。それ以外の場合は、デフォルトの Generate クラスのままにしてください。
カスタマイズオプションについては、後で別の章で詳しく説明します。
### 公開 API クラス
公開 API クラスは、アプリケーション開発者が Web アプリケーションのメッセージフローに正しい値を渡し、アクセストークンの検証やイントロスペクションなどを実行するために使用されます。
これらのクラスは %SYS.OAuth2 パッケージで実装されています。 次の表に、実装されているクラスの一部を掲載しています。
%SYS.OAuth2.AccessToken
Registered Object(登録オブジェクト)
%SYS.OAuth2.AccessToken クラスは、リソースサーバーへの認証にアクセストークンを使用できるようにするクライアント操作を定義します。基本となるトークンは、CACHESYS データベースの OAuth2.AccessToken に格納されます。 OAuth2.AccessToken は、SessionId と ApplicationName の組み合わせによってインデックス化されます。 したがって、SessionId/ApplicationName ごとに 1 つのスコープのみをリクエストできます。 2 回目のリクエストが別のスコープで行われ、アクセストークンがまだ付与されている場合は、新しいリクエストのスコープが予期されるスコープになります。
%SYS.OAuth2.Authorization
Registered Object(登録オブジェクト)
%SYS.OAuth2.Authorization クラスには、アクセストークンを取得してクライアントを認可するために使用される操作が含まれています。基本となるトークンは、CACHESYS データベースの OAuth2.AccessToken に格納されます。 OAuth2.AccessToken は、SessionId と ApplicationName の組み合わせによってインデックス化されます。 したがって、SessionId/ApplicationName ごとに 1 つのスコープのみをリクエストできます。 2 回目のリクエストが別のスコープで行われ、アクセストークンがまだ付与されている場合は、新しいリクエストのスコープが予期されるスコープになります。このクラスは CACHELIB にあるため、どこでも使用できることに注意してください。 ただし、トークンストレージは CACHESYS にあるため、ほとんどのコードでは直接使用できません。
%SYS.OAuth2.Validation
Registered Object(登録オブジェクト)
%SYS.OAuth2.Validation クラスは、アクセストークンの検証(または無効化)に使用されるメソッドを定義します。 基本となるトークンは、CACHESYS データベースの OAuth2.AccessToken に格納されます。 OAuth2.AccessToken は、SessionId と ApplicationName の組み合わせによってインデックス化されます。 したがって、SessionId/ApplicationName ごとに 1 つのスコープのみをリクエストできます。 2 回目のリクエストが別のスコープで行われ、アクセストークンがまだ付与されている場合は、新しいリクエストのスコープが予期されるスコープになります。
このグループのいくつかのメソッドとクラスを詳しく見てみましょう。
アクセストークンを使用するすべてのクライアントアプリケーションクラスは、その有効性をチェックする必要があります。 このチェックは、OnPage メソッド(または ZEN か ZENMojo ページの対応するメソッド)のどこかで実行されます。
こちらがそのコードスニペットです。
// OAuth2 サーバーからのアクセストークンがあるかどうかをチェックします。
set isAuthorized=##class(%SYS.OAuth2.AccessToken).IsAuthorized(..#OAUTH2APPNAME,,"scope1,
scope2",.accessToken,.idtoken,.responseProperties,.error)
// アクセストークンがあるかどうかをさらにチェックします。
// 以下は実行可能なすべてのテストであり、あらゆるケースで必要なわけではありません。
// 各テストで返される JSON オブジェクトが単に表示されています。
if isAuthorized {
// 何らかの処理を実行します – リソースサーバーの API を呼び出して目的のデータを取得します。
}
リソースサーバーの API を呼び出すたびに、アクセストークンを提供する必要があります。 この処理は、_%SYS.OAuth2.AccessToken_ メソッドの **AddAccessToken** メソッドによって実行されます。こちらがそのコードスニペットです。
set httpRequest=##class(%Net.HttpRequest).%New()
// AddAccessToken は現在のアクセストークンをリクエストに追加します。
set sc=##class(%SYS.OAuth2.AccessToken).AddAccessToken(
httpRequest,,
..#SSLCONFIG,
..#OAUTH2APPNAME)
if $$$ISOK(sc) {
set sc=httpRequest.Get(.. Service API url …)
}
この連載の前のパートで提供したサンプルコードでは、最初のアプリケーションページ(Cache1N)の OnPreHTTP メソッドでこのコードを確認することができました。 このコードは、アプリケーションの最初のページでアクセストークンチェックを実行するのに最適な場所です。
ClassMethod OnPreHTTP() As %Boolean [ ServerOnly = 1 ]
{
set scope="openid profile scope1 scope2"
#dim %response as %CSP.Response
if ##class(%SYS.OAuth2.AccessToken).IsAuthorized(..#OAUTH2APPNAME,,
scope,.accessToken,.idtoken,.responseProperties,.error) {
set %response.ServerSideRedirect="Web.OAUTH2.Cache2N.cls"
}
quit 1
}
上記のコードにある _SYS.OAuth2.AccessToken_ クラスの **IsAuthorized** メソッドは有効なアクセストークンが存在するかどうかをチェックし、存在しない場合に認可サーバーの認証フォームを指すログインボタン/リンクを使用してページの内容を表示し、存在する場合に実際にデータ取得処理を実行する 2 番目のページにリダイレクトします。
ただし、このコードは次のように変更できます。
ClassMethod OnPreHTTP() As %Boolean [ ServerOnly = 1 ]
{
set scope="openid profile scope1 scope2"
set sc=##class(%SYS.OAuth2.Authorization).GetAccessTokenAuthorizationCode(
..#OAUTH2APPNAME,scope,..#OAUTH2CLIENTREDIRECTURI,.properties)
quit +sc
}
この場合は、結果が異なります。 _%SYS.OAuth2.Authorization_ クラスの **GetAccessTokenAuthorizationCode** メソッドを使用すると、アプリケーションの最初のページの内容を表示せずに、認可サーバーの認証フォームに直接移動します。
これは、Web アプリケーションがモバイルデバイスのネイティブアプリケーションから呼び出され、一部のユーザー情報がネイティブアプリケーション(ランチャー)によってすでに表示されており、認可サーバーを指すボタンを含む Web ページを表示する必要がない場合に便利です。
署名付き JWT トークンを使用する場合は、その内容を検証する必要があります。 この検証は次のメソッドで実行されます。
set valid=##class(%SYS.OAuth2.Validation).ValidateJWT(applicationName,accessToken,scope,,.jsonObject,.securityParameters,.sc)
メソッドパラメーターの詳細については、Class Reference ドキュメントをご覧ください。
## カスタマイズ
OAUTH が認証 / 承認 UI のカスタマイズ用に提供しているオプションについてもう少し説明します。
勤務先のポリシーで、スコープの付与に関してより限定的な動作が要求されているとします。 たとえば、取引先銀行内のさまざまな金融システムに接続するホームバンキングアプリケーションを実行できるとしましょう。 銀行は、取得対象の実際の銀行口座に関する情報を含むスコープへのアクセスのみを許可します。 銀行は非常に多くの口座を運営しているため、すべての口座に静的なスコープを定義することは不可能です。 代わりに、認可処理中にその場でスコープを生成する処理をカスタム認可ページのコードに組み込むことができます。
デモを行うため、ここではサーバー構成にもう 1 つのスコープを追加する必要があります。次の画像を参照してください。

また、%OAuth2.Server.Authenticate.Bank という名前のカスタム Authenticate クラスへの参照も追加しました。
では、銀行の認証クラスはどのようになるのでしょうか? 次は想定されるクラスの例です。 このクラスは、ユーザーが提供するデータを使用して標準の認証フォームと認可フォームを拡張します。 **BeforeAuthenticate**、**DisplayPermissions**、**AfterAuthenticate** の各メソッド間を流れる情報は、_%OAuth2.Server.Properties_ クラスの _properties_ 変数によって渡されます。
Class %OAuth2.Server.Authenticate.Bank Extends %OAuth2.Server.Authenticate
{
/// account(口座)のスコープに CUSTOM BESTBANK のサポートを追加します。
ClassMethod BeforeAuthenticate(scope As %ArrayOfDataTypes, properties As %OAuth2.Server.Properties) As %Status
{
// 起動スコープが指定されていない場合は何もしません。
If 'scope.IsDefined("account") Quit $$$OK
// 起動クエリパラメーターから起動コンテキストを取得します。
Set tContext=properties.RequestProperties.GetAt("accno")
// コンテキストがない場合は何もしません。
If tContext="" Quit $$$OK
try {
// ここで BestBank コンテキストを照会する必要があります。
Set tBankAccountNumber=tContext
// accno のスコープを追加します。 -> 動的にスコープを変更(account なし:<accno> スコープはサーバー構成に存在します)
// この特定のスコープは、それが Cookie サポートを使用して account または account:accno によって
// 以前に選択されていた場合に account 経由で同じ accno にアクセスできるようにするために使用されます。
Do scope.SetAt("Access data for account "_tBankAccountNumber,"account:"_tBankAccountNumber)
// 処理が終わった account のスコープはもう必要ありません。
// これにより、account スコープが存在することで DisplayPermissions が強制的に呼び出されるのを防ぎます。
Do scope.RemoveAt("account")
// AfterAuthenticate が応答プロパティに変換する accno プロパティを追加します。
Do properties.CustomProperties.SetAt(tBankAccountNumber,"account_number")
} catch (e) {
s ^dk("err",$i(^dk("err")))=e.DisplayString()
}
Quit $$$OK
}
/// account のスコープに CUSTOM BESTBANK のサポートを追加します。
/// account_number カスタムプロパティが BeforeAuthenticate(account)または
/// DisplayPermissions(account:accno)によって追加された場合は、必要な応答プロパティを追加します。
ClassMethod AfterAuthenticate(scope As %ArrayOfDataTypes, properties As %OAuth2.Server.Properties) As %Status
{
// account_number(account)または accno(account:accno)プロパティが存在しない限り、ここで実行することは何もありません。
try {
// カスタムログを記録する例
If $$$SysLogLevel>=3 {
Do ##class(%OAuth2.Utils).LogServerScope("log ScopeArray-CUSTOM BESTBANK",%token)
}
If properties.CustomProperties.GetAt("account_number")'="" {
// 応答に accno クエリパラメーターを追加します。
Do properties.ResponseProperties.SetAt(properties.CustomProperties.GetAt("account_number"),"accno")
}
} catch (e) {
s ^dk("err",$i(^dk("err")))=e.DisplayString()
}
Quit $$$OK
}
/// BEST BANK の account のテキストを含むように変更された DisplayPermissions
ClassMethod DisplayPermissions(authorizationCode As %String, scopeArray As %ArrayOfDataTypes, currentScopeArray As %ArrayOfDataTypes, properties As %OAuth2.Server.Properties) As %Status
{
Set uilocales = properties.RequestProperties.GetAt("ui_locales")
Set tLang = ##class(%OAuth2.Utils).SelectLanguage(uilocales,"%OAuth2Login")
// $$$TextHTML(Text,Domain,Language)
Set ACCEPTHEADTITLE = $$$TextHTML("OAuth2 Permissions Page","%OAuth2Login",tLang)
Set USER = $$$TextHTML("User:","%OAuth2Login",tLang)
Set POLICY = $$$TextHTML("Policy","%OAuth2Login",tLang)
Set TERM = $$$TextHTML("Terms of service","%OAuth2Login",tLang)
Set ACCEPTCAPTION = $$$TextHTML("Accept","%OAuth2Login",tLang)
Set CANCELCAPTION = $$$TextHTML("Cancel","%OAuth2Login",tLang)
&html<<html>>
Do ..DrawAcceptHead(ACCEPTHEADTITLE)
Set divClass = "permissionForm"
Set logo = properties.ServerProperties.GetAt("logo_uri")
Set clientName = properties.ServerProperties.GetAt("client_name")
Set clienturi = properties.ServerProperties.GetAt("client_uri")
Set policyuri = properties.ServerProperties.GetAt("policy_uri")
Set tosuri = properties.ServerProperties.GetAt("tos_uri")
Set user = properties.GetClaimValue("preferred_username")
If user="" {
Set user = properties.GetClaimValue("sub")
}
&html<<body>>
&html<<div id="topLabel"></div>>
&html<<div class="#(divClass)#">>
If user '= "" {
&html<
<div>
<span id="left" class="userBox">#(USER)#<br>#(##class(%CSP.Page).EscapeHTML(user))#</span>
>
}
If logo '= "" {
Set espClientName = ##class(%CSP.Page).EscapeHTML(clientName)
&html<<span class="logoClass"><img src="#(logo)#" alt="#(espClientName)#" title="#(espClientName)#" align="middle"></span>>
}
If policyuri '= "" ! (tosuri '= "") {
&html<<span id="right" class="linkBox">>
If policyuri '= "" {
&html<<a href="#(policyuri)#" target="_blank">#(POLICY)#</a><br>>
}
If tosuri '= "" {
&html<<a href="#(tosuri)#" target="_blank">#(TERM)#</a>>
}
&html<</span>>
}
&html<</div>>
&html<<form>>
Write ##class(%CSP.Page).InsertHiddenField("","AuthorizationCode",authorizationCode),!
&html<<div>>
If $isobject(scopeArray), scopeArray.Count() > 0 {
Set tTitle = $$$TextHTML(" is requesting these permissions:","%OAuth2Login",tLang)
&html<<div class="permissionTitleRequest">>
If clienturi '= "" {
&html<<a href="#(clienturi)#" target="_blank">#(##class(%CSP.Page).EscapeHTML(clientName))#</a>>
} Else {
&html<#(##class(%CSP.Page).EscapeHTML(clientName))#>
}
&html<#(##class(%CSP.Page).EscapeHTML(tTitle))#</div>>
Set tCount = 0
Set scope = ""
For {
Set display = scopeArray.GetNext(.scope)
If scope = "" Quit
Set tCount = tCount + 1
If display = "" Set display = scope
Write "<div class='permissionItemRequest'>"_tCount_". "_##class(%CSP.Page).EscapeHTML(display)_"</div>"
}
}
If $isobject(currentScopeArray), currentScopeArray.Count() > 0 {
Set tTitle = $$$TextHTML(" already has these permissions:","%OAuth2Login",tLang)
&html<<div>>
&html<<div class="permissionTitleExisting">>
If clienturi '= "" {
&html<<a href="#(clienturi)#" target="_blank">#(##class(%CSP.Page).EscapeHTML(clientName))#</a>>
} Else {
&html<#(##class(%CSP.Page).EscapeHTML(clientName))#>
}
&html<#(##class(%CSP.Page).EscapeHTML(tTitle))#</div>>
Set tCount = 0
Set scope = ""
For {
Set display = currentScopeArray.GetNext(.scope)
If scope = "" Quit
Set tCount = tCount + 1
If display = "" Set display = scope
Write "<div class='permissionItemExisting'>"_tCount_". "_##class(%CSP.Page).EscapeHTML(display)_"</div>"
}
&html<</div>>
}
/*********************************/
/* BEST BANK CUSTOMIZATION */
/*********************************/
try {
If properties.CustomProperties.GetAt("account_number")'="" {
// Display the account number obtained from account context.
Write "<div class='permissionItemRequest'><b>Selected account is "_properties.CustomProperties.GetAt("account_number")_"</b></div>",!
// or, alternatively, let user add some more information at this stage (e.g. linked account number)
//Write "<div>Account Number: <input type='text' id='accno' name='p_accno' placeholder='accno' autocomplete='off' ></div>",!
}
} catch (e) {
s ^dk("err",$i(^dk("err")))=e.DisplayString()
}
/* original implementation code continues here... */
&html<
<div><input type="submit" id="btnAccept" name="Accept" value="#(ACCEPTCAPTION)#"/></div>
<div><input type="submit" id="btnCancel" name="Cancel" value="#(CANCELCAPTION)#"/></div>
>
&html<</form>
</div>>
Do ..DrawFooter()
&html<</body>>
&html<<html>>
Quit 1
}
/// CUSTOM BESTBANK の場合、入力された患者を検証する必要があります。
/// ! このメソッドの javascript はユーザーに追加データを DisplayPermissions メソッド内
/// で入力させる場合にのみ必要です !
ClassMethod DrawAcceptHead(ACCEPTHEADTITLE)
{
&html<<head><title>#(ACCEPTHEADTITLE)#</title>>
Do ..DrawStyle()
&html<
<script type="text/javascript">
function doAccept()
{
var accno = document.getElementById("accno").value;
var errors = "";
if (accno !== null) {
if (accno.length < 1) {
errors = "Please enter account number name";
}
}
if (errors) {
alert(errors);
return false;
}
// submit the form
return true;
}
</script>
>
&html<</head>>
}
}
ご覧のとおり、%OAuth2.Server.Properties クラスにはいくつかの配列が含まれており、渡されています。 具体的には、以下の配列です。
· RequestProperties – 認可リクエストのパラメーターが含まれています。
· CustomProperties – 上記のコードの間でデータをやり取りするためのコンテナ。
· ResponseProperties – トークンリクエストに対する JSON 応答オブジェクトに追加されるプロパティのコンテナ。
· ServerProperties – 認可サーバーがカスタマイズコードに公開する共有プロパティが含まれます(logo_uri、client_uri など…)
さらに、認可サーバーが返す必要のあるクレームを指定するのに使用されるいくつかの "claims" プロパティが含まれています。
この認証ページを正しく呼び出すため、最初のクライアントページのコードを次のように変更しました。
set scope="openid profile scope1 scope2 account"
// このデータはアプリケーションに由来し(フォームデータなど)、リクエストのコンテキストを設定します。
// ここでは Authenticate クラスをサブクラス化することで、このデータをユーザーに表示することができます。
// それにより、該当ユーザーはアクセスを許可するかどうかを決めることができます。
set properties("accno")="75-452152122-5320"
set url=##class(%SYS.OAuth2.Authorization).GetAuthorizationCodeEndpoint(
..#OAUTH2APPNAME,
scope,
..#OAUTH2CLIENTREDIRECTURI,
.properties,
.isAuthorized,
.sc)
if $$$ISERR(sc) {
write "GetAuthorizationCodeEndpoint Error="
write ..EscapeHTML($system.Status.GetErrorText(sc))_"<br>",!
}
ご覧のとおり、ここではアプリケーションのさまざまな部分から発生する可能性のあるコンテキスト値を使用して account のスコープとプロパティ配列ノード “accno” を追加しました。 この値はアクセストークンの内部でリソースサーバーに渡され、さらに処理されます。
上記のロジックは、電子的な患者記録を交換するための FHIR 標準で実際に使用されています。
デバッグ
OAUTH フレームワークには、デバッグ機能が組み込まれています。 クライアントとサーバー間の通信はすべて暗号化されているため、これは非常に便利です。 デバッグ機能を使用すると、API クラスによって生成されたトラフィックデータをネットワーク経由で送信する前にキャプチャできます。 コードをデバッグするため、以下のコードに従って単純なルーチンまたはクラスを実装できます。 InterSystems IRIS インスタンスのすべての通信でこのコードを実装する必要があることに注意してください! その場合、OAUTH フローのプロセス内での役割を示す名前をファイル名に指定することをお勧めします。 (以下のサンプルコードは rr.mac ルーチンとして保存されていますが、どんな名前を付けるかはあなた次第です。)
// d start^rr()
start() public {
new $namespace
set $namespace="%sys"
kill ^%ISCLOG
set ^%ISCLOG=5
set ^%ISCLOG("Category","OAuth2")=5
set ^%ISCLOG("Category","OAuth2Server")=5
quit
}
// d stop^rr()
stop() public {
new $namespace
set $namespace="%sys"
set ^%ISCLOG=0
set ^%ISCLOG("Category","OAuth2")=0
set ^%ISCLOG("Category","OAuth2Server")=0
quit
}
// display^rr()
display() public {
new $namespace
set $namespace="%sys"
do ##class(%OAuth2.Utils).DisplayLog("c:\temp\oauth2_auth_server.log")
quit
}
次に、テストを開始する前にターミナルを開き、すべての InterSystems IRIS ノード(クライアント、認可サーバー、リソースサーバー)で d start^rr() を呼び出してください。 完了後、d stop^rr() と d display^rr() を実行してログファイルを読み込んでください。
最後に
この連載記事では、InterSystems IRIS OAuth 2.0 の実装を使用する方法を学びました。 パート1では簡単なクライアントアプリケーションのデモを行い、パート2では複雑な例を説明しました。 最後に、OAuth 2.0 の実装で最も重要なクラスについて説明し、ユーザーアプリケーション内でそれらを呼び出す必要がある場合について説明しました。
時々私が投げかけるくだらない質問に我慢強く回答し、この連載をレビューしてくれた Marvin Tener に心から感謝の意を表します。
記事
Shintaro Kaminaka · 2020年8月20日
作成者:Daniel Kutac(InterSystems セールスエンジニア)
注意: _*使用されている URL に戸惑っている方のために*。*元の連載記事では、dk-gs2016 と呼ばれるマシンの画面を使用していました。 新しいスクリーンショットは別のマシンから取得されています。 **WIN-U9J96QBJSAG という URL は dk-gs2016*_ であると見なしても構いません。
### パート2. 認可サーバー、OpenID Connect サーバー
この短い連載の[前のパート](https://jp.community.intersystems.com/node/478821)では、OAUTH[[1](#note1)] クライアントとして機能する単純な使用事例について学びました。 今回は私たちの経験をまったく新しいレベルに引き上げましょう。 InterSystems IRIS がすべての OAUTH の役割を果たす、より複雑な環境を構築します。
クライアントの作成方法はすでに分かっていますので、認可サーバーだけでなく、OpenID Connect[[2](#note2)] プロバイダーにも注意を向けましょう。
前のパートと同様に、環境を準備する必要があります。 今回はより多くの変動要素があるため、より注意を要します。
具体例を見る前に、OpenID Connect について少し説明する必要があります。
前のパートの内容を覚えていらっしゃるかと思いますが、Google から認可してもらうため、まずは自身がGoogle で認証を受けることを求められていました。 認証は OAUTH フレームワークには含まれていません。 実際、OAUTH に依存しない多くの認証フレームワークがあります。 そのうちの1つに OpenID と呼ばれるものがあります。 当初は単独の構想で開始されましたが、最近では OAUTH フレームワークによって提供されるインフラストラクチャ、つまり通信とデータ構造が活用されています。 その結果、OpenID Connect が誕生しました。 事実、多くの人がこれを OAUTH の強化版と呼んでいます。 実際、OpenID Connect を使用すると、認可するだけでなく、OAUTH フレームワークのよく知られたインターフェースを使用して認証することもできます。
# 複雑な OpenID Connect のデモ
ここでは、パート 1 のクライアントコードの多くを活用します。 そうすることで多くの手間が省けるため、環境のセットアップに集中できます。
## 前提条件
今回は、SSL が有効になっている既存の Web サーバーに PKI インフラストラクチャを追加する必要があります。 OpenID Connect の要件である暗号化が必要です。 ユーザー認証が必要な場合は、第三者がエージェント(クライアント、認証サーバーなど)になりすますし、ネットワーク経由でユーザーの機密データを送信できないようにする必要があります。 そこで X.509 ベースの暗号化の出番です。
注意 : Cache 2017.1 以降では、X.509 証明書を使用して JWT / JWKS(JSON Web Key Set)を生成する必要はありません。 ここでは下位互換性と単純化を図るためにこのオプションを使用しています。
### PKI
厳密に言えば、Caché PKI インフラストラクチャを使用する必要はまったくありません。ただし、openssl などのツールを直接使用してすべての証明書を生成するよりは楽です。
詳細は InterSystems IRIS の[ドキュメント](http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=GCAS_pki#GCAS_C157792)や他の場所でも確認できますので、ここでは証明書の生成に関する詳細は触れません。 証明書を生成した結果、3 つの公開鍵/秘密鍵のペアと関連する証明書が作成されます。
これらを次のように呼びます。
* 発行元認証局の root_ca(root_ca.cer)
* 認可サーバーおよび OpenID サーバー用の auth(auth.cer および auth.key)
* クライアントアプリケーションサーバー用の client(client.cer および client.key)
### X.509 資格情報
デモ中に交換された JSON Web Token(JWT)に署名して検証できるよう、個々のサーバーで X.509 資格情報を定義する必要があります。
### 認可サーバーと認証サーバーの構成
ここでは X.509 資格情報の定義方法については詳しく説明せず、AUTHSERVER インスタンスの資格情報のスクリーンショットを示します。

画像のように、AUTHSERVER にはその秘密鍵と証明書がありますが、CLIENT に関しては公開鍵を含む証明書しかありません。
### **クライアントサーバーの構成**
同様に、CLIENT インスタンスで資格情報が定義されています。

ここで、CLIENT には秘密鍵と証明書がありますが、AUTHSERVER に関しては公開鍵を含む証明書しかありません。
### **リソースサーバーの構成**
このセットアップの例では、RESSERVER インスタンスで X509 資格情報を定義する必要はありません。
## **OAUTH の構成**
この連載のパート 1 で説明した構成と同様に、サーバーを OAUTH 用に構成する必要があります。 まずは、OAUTH 構成全体の中心的なコンポーネントである AUTHSERVER インスタンスから始めましょう。
### **AUTHSERVER**
System Management Portal で、**System Administration > Security > OAuth 2.0 > Server Configuration** を開きます。
メニューのリンクをクリックし、次のフォーム項目に入力します。
* Host name(ホスト名)
* Port(ポート、省略可)
* Prefix(プレフィックス、省略可) – これら 3 つのフィールドは *Issuer endpoint*(発行者エンドポイント)を構成します。
* 更新トークンを返す条件を指定します。
* Supported grant types(サポートされているグラント種別)をチェックします。このデモでは 4 つの種別すべてにチェックします。 ただし、認可コードのみが使用されます。
* 必要に応じて Audience required(オーディエンスを要求)をチェックします。これにより、*aud* プロパティが認可コードと暗黙的な許可(Implicit)のリクエストに追加されます。
* 必要に応じて Support user session(ユーザーセッションをサポート)をチェックします。これにより、認可サーバーが現在このブラウザを使用しているユーザーのログイン状態を維持するために *httpOnly* Cookie が使用されます。 2 回目以降のアクセストークンの要求では、ユーザー名とパスワードの入力は求められません。
* Endpoint intervals(エンドポイントの間隔)を指定します。
* このサーバーでサポートされるスコープ(Supportted scopes)を定義します。
* Customization Options(カスタマイズオプション)のデフォルト値を受け入れるか、カスタム値を入力します。**注意: **JWT が単なる opaque トークンではなくアクセストークンとして使用されるよう、Generate token class(生成トークンクラス)の値を **%OAuth2.Server.Generate** から **%OAuth2.Server.JWT** に変更してください。
* OAuth 2.0 の要求に従い、HTTP 上の SSL を確立するための登録済み SSL 構成の名前を入力します。
* JSON Web Token(JWT)の設定を入力します。
以下はサンプル構成のスクリーンショットです。





サーバー構成を定義したら、サーバークライアント構成を入力する必要があります。 サーバー構成フォームのページ内で、「Client Configurations」(クライアント構成)ボタンをクリックし、CLIENT インスタンスおよび RESSERVER インスタンスの「Create New Configuration」(新しい構成の作成)をクリックします。
(IRISを使用して構成している場合は、「クライアントディスクリプション」の構成ページから以下の設定を行います。)
以下の画像は CLIENT の構成を示しています。



JWT Token(JWT トークン)タブはデフォルト値である空のままにします。 ご覧のとおり、実際のアプリケーションの場合とは異なり、フィールドには無意味なデータが入力されています。
同様に、RESSERVER の構成を示します。


ご覧のとおり、リソースサーバーに必要なのは非常に基本的な情報だけです。具体的には、Client type(クライアント種別)をリソースサーバーに設定する必要があります。 CLIENT では、より詳細な情報とクライアント種別を入力する必要があります(クライアントはクライアントシークレットをサーバーで維持し、クライアントエージェントには送信しない Web アプリケーションとして動作するため、機密(confidential)を選択します)。
### **CLIENT**
SMP で、**System Administration > Security > OAuth 2.0 > Client Configurations** を開きます。
「Create Server Configuration」(サーバー構成の作成)ボタンをクリックし、フォームに入力して保存します。

Issuer Endpoint(発行者エンドポイント)が、AUTHSERVER インスタンスで前に定義した値に対応していることを必ず確認してください! また、認可サーバーのエンドポイントを Web サーバーの構成に従って変更する必要があります。 この場合は各入力フィールドに「authserver」を埋め込んだだけです。
次に、新しく作成された発行者エンドポイントの横にある「**Client Configurations**」(クライアント構成)リンクをクリックし、「**Create Client Configuration**」(クライアント構成の作成)ボタンをクリックします。




以上です! ここまでの手順で CLIENT と AUTHSERVER の両方を構成しました。 多くの使用事例ではこれだけで十分です。リソースサーバーは単なる AUTHSERVER のネームスペースにすぎず、結果的にすでに保護されている場合があるからです。 しかし、外部の医師が内部の臨床システムからデータを取得しようとしている使用事例に対応する場合を考えてみましょう。 このような医師がデータを取得できるようにするため、この医師のアカウント情報を監査目的と法医学的な理由でリソースサーバー内に確実に保存したいと思います。 この場合は、続けて RESSERVER を定義する必要があります。
### **RESSERVER**
SMP で、**System Administration > Security > OAuth 2.0 > Client Configurations** を開きます。
「**Create Server Configuration**」(サーバー構成の作成)ボタンをクリックし、フォームに入力して保存します。

ここでは、Cache 2017.1 に実装された新機能である検出機能を使用しました。
ご覧のように、この構成は CLIENT インスタンスの対応する構成と同じデータを使用しています。
次に、新しく作成された発行者エンドポイントの横にある「**Client Configurations**」(クライアント構成)リンクをクリックし、「**Create Client Configuration**」(クライアント構成の作成)ボタンをクリックします。


X.509 資格情報から JWT を作成することはお勧めしませんが、ここでは互換性のために使用しました。

CLIENTとほとんど同じ手順でしたが、必要なものでした。 しかし、これで先に進んでコーディングできるようになりました!
## **クライアントアプリケーション**
話をできる限り簡単にするため、パート1で説明した Google の例から多くのコードをリサイクルします。
クライアントアプリケーションは /csp/myclient で実行されるわずか 2 つの CSP ページからなるアプリケーションです。セキュリティは強制せず、未認証ユーザーとして実行されます。
### **ページ 1**
Class Web.OAUTH2.Cache1N Extends %CSP.Page
{
Parameter OAUTH2CLIENTREDIRECTURI = "https://dk-gs2016/client/csp/myclient/Web.OAUTH2.Cache2N.cls";
Parameter OAUTH2APPNAME = "demo client";
ClassMethod OnPage() As %Status
{
&html
// 適切なリダイレクトとスコープを持つ認証エンドポイントの URL を取得します。
// 返された URL は下のボタンで使用されます。
// DK: 'dankut' アカウントを使用して認証します!
set scope="openid profile scope1 scope2"
set url=##class(%SYS.OAuth2.Authorization).GetAuthorizationCodeEndpoint(
..#OAUTH2APPNAME,
scope,
..#OAUTH2CLIENTREDIRECTURI,
.properties,
.isAuthorized,
.sc)
if $$$ISERR(sc) {
write "GetAuthorizationCodeEndpoint Error="
write ..EscapeHTML($system.Status.GetErrorText(sc))_"",!
}
&html<
Authorize for ISC
>
Quit $$$OK
}
ClassMethod OnPreHTTP() As %Boolean [ ServerOnly = 1 ]
{
#dim %response as %CSP.Response
set scope="openid profile scope1 scope2"
if ##class(%SYS.OAuth2.AccessToken).IsAuthorized(..#OAUTH2APPNAME,,scope,.accessToken,.idtoken,.responseProperties,.error) {
set %response.ServerSideRedirect="Web.OAUTH2.Cache2N.cls"
}
quit 1
}
}
### **ページ 2**
Class Web.OAUTH2.Cache2N Extends %CSP.Page
{
Parameter OAUTH2APPNAME = "demo client";
Parameter OAUTH2ROOT = "https://dk-gs2016/resserver";
Parameter SSLCONFIG = "SSL4CLIENT";
ClassMethod OnPage() As %Status
{
&html
// OAuth2 サーバーからのアクセストークンがあるかどうかをチェックします。
set isAuthorized=##class(%SYS.OAuth2.AccessToken).IsAuthorized(..#OAUTH2APPNAME,,"scope1 scope2",.accessToken,.idtoken,.responseProperties,.error)
// アクセストークンがあるかどうかをさらにチェックします。
// 以下は実行可能なすべてのテストであり、あらゆるケースで必要なわけではありません。
// 各テストで返される JSON オブジェクトが単に表示されています。
if isAuthorized {
write "Authorized!",!
// JWT の場合、検証してからアクセストークンから詳細を取得します。
set valid=##class(%SYS.OAuth2.Validation).ValidateJWT(..#OAUTH2APPNAME,accessToken,"scope1 scope2",,.jsonObject,.securityParameters,.sc)
if $$$ISOK(sc) {
if valid {
write "Valid JWT"_"",!
} else {
write "Invalid JWT"_"",!
}
write "Access token="
do jsonObject.%ToJSON()
write "",!
} else {
write "JWT Error="_..EscapeHTML($system.Status.GetErrorText(sc))_"",!
}
write "",!
// イントロスペクションエンドポイントを呼び出して結果を表示します。RFC 7662 を参照してください。
set sc=##class(%SYS.OAuth2.AccessToken).GetIntrospection(..#OAUTH2APPNAME,accessToken,.jsonObject)
if $$$ISOK(sc) {
write "Introspection="
do jsonObject.%ToJSON()
write "",!
} else {
write "Introspection Error="_..EscapeHTML($system.Status.GetErrorText(sc))_"",!
}
write "",!
if idtoken'="" {
// ID トークンの検証と表示。OpenID Connect Core の仕様を参照してください。
set valid=##class(%SYS.OAuth2.Validation).ValidateIDToken(
..#OAUTH2APPNAME,
idtoken,
accessToken,,,
.jsonObject,
.securityParameters,
.sc)
if $$$ISOK(sc) {
if valid {
write "Valid IDToken"_"",!
} else {
write "Invalid IDToken"_"",!
}
write "IDToken="
do jsonObject.%ToJSON()
write "",!
} else {
write "IDToken Error="_..EscapeHTML($system.Status.GetErrorText(sc))_"",!
}
} else {
write "No IDToken returned"_"",!
}
write "",!
// アプリケーションロジックには不要ですが、委任認証に渡すことができるユーザーに関する情報を提供します。
// Userinfo エンドポイントを呼び出して結果を表示します。OpenID Connect Core の仕様を参照してください。
set sc=##class(%SYS.OAuth2.AccessToken).GetUserinfo(
..#OAUTH2APPNAME,
accessToken,,
.jsonObject)
if $$$ISOK(sc) {
write "Userinfo="
do jsonObject.%ToJSON()
write "",!
} else {
write "Userinfo Error="_..EscapeHTML($system.Status.GetErrorText(sc))_"",!
}
write "",!
/***************************************************
* *
* リソースサーバーを呼び出し、結果を表示します。 *
* *
***************************************************/
// オプション 1 - リソースサーバー - 定義によれば認可サーバーからのデータを信頼します。
// そのため、リソースサーバーに渡されたアクセストークンが有効である限り
// 要求元を問わずデータを提供します。
// オプション 2 - または委任認証(OpenID Connect)を使用して
// (委任認証を保護して)別の CSP アプリケーションを呼び出すこともできます。
// - これはまさにこのデモで実施する内容です。
write "リソースサーバーの呼び出し(委任認証)","",!
set httpRequest=##class(%Net.HttpRequest).%New()
// AddAccessToken は現在のアクセストークンをリクエストに追加します。
set sc=##class(%SYS.OAuth2.AccessToken).AddAccessToken(
httpRequest,,
..#SSLCONFIG,
..#OAUTH2APPNAME)
if $$$ISOK(sc) {
set sc=httpRequest.Get(..#OAUTH2ROOT_"/csp/portfolio/oauth2test.demoResource.cls")
}
if $$$ISOK(sc) {
set body=httpRequest.HttpResponse.Data
if $isobject(body) {
do body.Rewind()
set body=body.Read()
}
write body,"",!
}
if $$$ISERR(sc) {
write "Resource Server Error="_..EscapeHTML($system.Status.GetErrorText(sc))_"",!
}
write "",!
write "Call resource server - no auth, just token validity check","",!
set httpRequest=##class(%Net.HttpRequest).%New()
// AddAccessTokenは現在のアクセストークンをリクエストに追加します。
set sc=##class(%SYS.OAuth2.AccessToken).AddAccessToken(
httpRequest,,
..#SSLCONFIG,
..#OAUTH2APPNAME)
if $$$ISOK(sc) {
set sc=httpRequest.Get(..#OAUTH2ROOT_"/csp/portfolio2/oauth2test.demoResource.cls")
}
if $$$ISOK(sc) {
set body=httpRequest.HttpResponse.Data
if $isobject(body) {
do body.Rewind()
set body=body.Read()
}
write body,"",!
}
if $$$ISERR(sc) {
write "Resource Server Error="_..EscapeHTML($system.Status.GetErrorText(sc))_"",!
}
write "",!
} else {
write "Not Authorized!",!
write "Authorize me"
}
&html
Quit $$$OK
}
}
次のスクリーンショットで処理を説明します。
AUTHSERVER インスタンスの認可 / OpenID Connect 認証サーバーのログインページ

AUTHSERVER のユーザー同意ページ

その後、最終的に結果ページが表示されます。

ご覧のとおり、実際にコードを読んでもパート 1 で示したクライアントのコードとほとんど違いはありません。 ページ 2 には違いがあります。 これはデバッグ情報であり、JWT の有効性をチェックしています。 返ってきた JWT を検証した後、AUTHSERVER からのユーザー識別情報に関するデータに対してイントロスペクションを実行できました。 ここではこの情報をページに出力しただけですが、それ以上のこともできます。 上記で説明した外部の医師の使用事例と同様に、必要に応じて識別情報を使用し、それを認証目的でリソースサーバーに渡すことができます。 または、この情報をパラメーターとしてリソースサーバーへの API 呼び出しに渡すこともできます。
次の段落では、ユーザー識別情報の使用方法について詳しく説明します。
## **リソースアプリケーション**
リソースサーバーは認可 / 認証サーバーと同じサーバーにすることができ、多くの場合はそうなります。 しかし、このデモでは 2 つのサーバーを独立した InterSystems IRIS インスタンスにしました。
したがって、リソースサーバーでセキュリティコンテキストを使用する方法には 2 つあります。
### **方法 1 – 認証なし**
これは最も単純なケースです。 認可 / 認証サーバーはまったく同じ Caché インスタンスです。 この場合、単一の目的のために特別に作成された csp アプリケーションにアクセストークンを渡すだけで、OAUTH を使用するクライアントアプリケーションにデータを提供し、データを要求することを認可できます。
リソース csp アプリケーションの構成(ここでは /csp/portfolio2 と呼びました)は、以下のスクリーンショットのようになります。

最小限のセキュリティをアプリケーション定義に組み込み、特定の CSP ページのみを実行できるようにします。
または、リソースサーバーは従来の Web ページの代わりに REST API を提供できます。 実際のシナリオでは、セキュリティコンテキストを微調整するのはユーザー次第です。
ソースコードの例:
Class oauth2test.demoResource Extends %CSP.Page
{
ClassMethod OnPage() As %Status
{
set accessToken=##class(%SYS.OAuth2.AccessToken).GetAccessTokenFromRequest(.sc)
if $$$ISOK(sc) {
set sc=##class(%SYS.OAuth2.AccessToken).GetIntrospection("RESSERVER resource",accessToken,.jsonObject)
if $$$ISOK(sc) {
// 必要に応じて jsonObject のフィールドを検証します
w "Hello from Caché server: /csp/portfolio2 application!"
w "running code as $username = "_$username_" with following $roles = "_$roles_" at node "_$p($zu(86),"*",2)_"."
}
} else {
w "NOT AUTHORIZED!"
w ""
w
i $d(%objlasterror) d $system.OBJ.DisplayError()
w ""
}
Quit $$$OK
}
}
### **方法 2 – 委任認証**
これはもう 1 つの極端なケースです。ユーザーがリソースサーバーの内部ユーザーと同等のセキュリティコンテキストで作業しているかのように、リソースサーバーでユーザーの識別情報を可能な限り最大限に活用したいと考えています。
解決方法の 1 つは、委任認証を使用することです。
この方法を実行するには、さらにいくつかの手順を実行してリソースサーバーを構成する必要があります。
· 委任認証を有効にする
· ZAUTHENTICATE ルーチンを提供する
· Web アプリケーションを構成する(この場合、/csp/portfolio で呼び出しました)
ここではユーザー識別情報とそのスコープ(セキュリティプロファイル)を提供した AUTHSERVER を信頼しているため、ZAUTHENTICATE ルーチンの実装は非常に単純で簡単です。そのため、ここではいかなるユーザー名も受け入れ、それをスコープと共にリソースサーバーのユーザーデータベースに渡しています(OAUTH スコープと InterSystems IRIS のロール間で必要な変換を行ったうえで)。 それだけです。 残りの処理は InterSystems IRIS によってシームレスに行われます。
これは ZAUTHENTICATE ルーチンの例です。
#include %occErrors
#include %occInclude
ZAUTHENTICATE(ServiceName, Namespace, Username, Password, Credentials, Properties) PUBLIC
{
set tRes=$SYSTEM.Status.OK()
try {
set Properties("FullName")="OAuth account "_Username
//set Properties("Roles")=Credentials("scope")
set Properties("Username")=Username
//set Properties("Password")=Password
// Credentials 配列を GetCredentials() メソッドから渡せないため、一時的に書き換えます。
set Properties("Password")="xxx" // OAuth2 アカウントのパスワードは気にしません。
set Properties("Roles")=Password
} catch (ex) {
set tRes=$SYSTEM.Status.Error($$$AccessDenied)
}
quit tRes
}
GetCredentials(ServiceName,Namespace,Username,Password,Credentials) Public
{
s ts=$zts
set tRes=$SYSTEM.Status.Error($$$AccessDenied)
try {
If ServiceName="%Service_CSP" {
set accessToken=##class(%SYS.OAuth2.AccessToken).GetAccessTokenFromRequest(.sc)
if $$$ISOK(sc) {
set sc=##class(%SYS.OAuth2.AccessToken).GetIntrospection("RESSERVER resource",accessToken,.jsonObject)
if $$$ISOK(sc) {
// ToDo: 標準アカウントと委任されたアカウント(OpenID)が競合する可能性があるため、注意してください!
set Username=jsonObject.username
set Credentials("scope")=$p(jsonObject.scope,"openid profile ",2)
set Credentials("namespace")=Namespace
// temporary hack
//set Password="xxx"
set Password=$tr(Credentials("scope")," ",",")
set tRes=$SYSTEM.Status.OK()
} else {
set tRes=$SYSTEM.Status.Error($$$GetCredentialsFailed)
}
}
} else {
set tRes=$SYSTEM.Status.Error($$$AccessDenied)
}
} catch (ex) {
set tRes=$SYSTEM.Status.Error($$$GetCredentialsFailed)
}
Quit tRes
}
CSP ページ自体は非常にシンプルになります。
Class oauth2test.demoResource Extends %CSP.Page
{
ClassMethod OnPage() As %Status
{
// アクセストークン認証は委任認証によって実行されます!
// もう一度ここで行う必要はありません。
// これはリクエストからアクセストークンを取得し、イントロスペクションエンドポイントを
// 使用してアクセストークンの有効性を確認するダミーのリソースサーバーです。
// 通常、応答はセキュリティに関連しませんが、リクエストパラメーターに基づく
// 興味深いデータが含まれている可能性があります。
w "Hello from Caché server: /csp/portfolio application!"
w "running code as $username = "_$username_" with following $roles = "_$roles_" at node "_$p($zu(86),"*",2)_"."
Quit $$$OK
}
}
そして最後に、/csp/portfolio の Web アプリケーション構成を示します。

あなたが本当に心配であったなら、最初のバリエーションで行ったように _Permitted クラス_を設定できたかもしれません。 または、REST API を使用していたかもしれません。 しかし、これらの設定に関してはこの記事の中では説明しません。
次回は、InterSystems IRIS OAUTH フレームワークによって導入される個々のクラスについて説明します。 それらの API、およびそれらを呼び出すタイミングと場所について説明します。
[1] この記事で OAUTH について言及する場合、常に RFC 6749()で規定されている OAuth 2.0 を指しています。 ここでは簡略化のために短縮形の OAUTH を使用しています。
[2] OpenID Connect は OpenID Foundation()によって管理されています。
記事
Mihoko Iijima · 2020年10月27日
この記事はこちらの投稿の続きの内容です。
前回の記事では、Interoperability(相互運用性)メニューを利用してシステム統合を行う際、どのような仕組みで動作しているのかについて解説しました。
今回の記事では、Interoperability(相互運用性)メニューを利用してでシステム統合を行うためにどのような開発を行うのか、について解説します。
最初に、どんな流れを作りたいのか?を考えながら、以下の内容を作成していきます。
プロダクション
メッセージ
コンポーネント
ビジネス・サービス
ビジネス・プロセス
ビジネス・オペレーション
プロダクション については、システム統合を行うために必要なコンポーネントの指定と、コンポーネントの設定を保存しておくため定義で、管理ポータルを使用して設定します(内部的にはプロダクション用クラス定義として保存されます)。
例えば、一定間隔で指定ディレクトリに置かれたファイルを処理するビジネス・サービスを作成している場合、「どのディレクトリを監視するのか」「どのファイルを処理したらいいのか」を具体的に設定します。この設定を保存するために用意するのが プロダクション です。
なお、設定内容はデータを送受信するコンポーネントが使用するアダプタにより異なります。
アダプタとは、外部システムとの接続を簡単にするためのクラスで、メール/ファイル/SOAP/FTP/HTTP/SQL/TCP などプロトコル別のものもあれば、HL7など規格に対応したアダプタもあります。
アダプタ詳細についてドキュメント(プロトコル別のアダプタ や EDIドキュメントに関連するアダプタ)をご参照ください。
プロダクションには必要なコンポーネントを定義しておくので、「プロダクションを開始」することでシステム統合が開始し、「プロダクションを停止」することでシステム統合が停止します。
プロダクションを完成させるために必要な開発は、システム統合に必要な部品の作成ですが、具体的には以下の内容を作成します。
メッセージ
コンポーネント(ビジネス・サービス/ビジネス・プロセス/ビジネス・オペレーション)
データ変換 などなど
上記内容はこの後の記事でゆっくり解説します。
まずは、サンプルのプロダクションを利用してプロダクションを開始し、設定内容を確認しながら実際にデータを流してメッセージの流れを確認してみましょう。
サンプルは https://github.com/Intersystems-jp/selflearning-interoperability からダウンロードいただけます。
コンテナを利用される場合は、git clone でサンプルコードをダウンロードいただき、clone で作成したディレクトリに移動後、docker-compose up -d を実行するだけ!とても簡単です。手順はこちらをご参照ください(コンテナ作成に少し時間がかかります)。
コンテナを利用されない場合は、サンプルダウンロード後、新規でネームスペースを作成し、作成したネームスペースに src フォルダ以下にあるクラス定義ファイル(拡張子.cls)をすべてインポートしてください。ネームスペース作成の流れなどは、こちらの記事の 07:03以降のビデオをご参照ください。
サンプルコード詳細については README もぜひご参照ください。
準備ができたら、管理ポータルにアクセスします(Webサーバのポート番号はご利用環境に合わせて変更してください)。
localhost:52773/csp/sys/UtilHome.csp
管理ポータル > [Interoperability] > [構成] > [プロダクション] にアクセスします.
コンテナ以外をご利用の場合はソースコードをインポートしたネームスペースに接続してから[構成] > [プロダクション] にアクセスし [開く] ボタンをクリックし [Start] > [Production] を選択したあと [開始する] ボタンをクリックします。
※コンテナ以外をご利用の場合は、初期設定が必要です。後述の内容を事前に設定してからこの後の内容をお試しください
プロダクションの画面は「サービス」「プロセス」「オペレーション」のコンポーネントごとに [●コンポーネント名] と表示されます。
コンポーネント名をクリックすると、画面右端の「設定」タブの内容が変わります。
例えば、Start.GetKionOperation をクリック(シングルクリック)したときの表示は以下の通りです。
このコンポーネントは Web API に接続するための [HTTPサーバ] [URL] の設定があります。設定の下の方には API key を入力するための [appid] 欄があります。ここに取得した API key を入力し「適用」ボタンをクリックします。
コンテナをご利用の方はこれで設定は完了です。つづきはこちらをご覧ください。
コンテナ以外でお試しいただいてる方
事前に以下2つの設定を行ってください。
1) SSLクライアントの設定。
接続先の Web API の通信が https で行われるため、事前にIRIS側に SSLクライアントの設定を行います。サンプルプロダクションの設定に合わせるため、[openweather] の名称で作成します。プロダクション上の設定は以下の通りです。
管理ポータル > [システム管理] > [セキュリティ] > [SSL/TLS 構成] > [新規構成の作成]ボタンクリックし、「構成名」に openweather と記入したら「保存」ボタンをクリックして終了です。
2) REST用ベースURLの作成
サンプルプロダクションでは、RESTで情報入力できるように設定しています。IRIS 側の設定として REST のベースURL を設定しておく必要があります。例では、/start をベースURLに設定しています。サンプルをインポートしたネームスペースに Start.REST クラスが存在しますので、このクラスをディスパッチクラスに指定し、アクセス時の認証を省略したいので、アプリケーションロールとして %All を追加します。
管理ポータル > [システム管理] > [セキュリティ] > [アプリケーション] > [ウェブ・アプリケーションパス] > [新しいウェブ・アプリケーションを作成] ボタンをクリックします。
名前欄に /start 、ネームスペースにサンプルをインポートされたネームスぺ―スを指定、ディスパッチクラス名に Start.REST を指定、許可された認証方法に「認証なし」を選択し、一旦保存します。
保存後、「アプリケーションロール」タブで %All ロールをアプリケーションロールに追加します。
データを送信してみる
準備ができたら、REST で情報を送信できるビジネスサービスを利用して、情報を流してみます。
http://localhost:52773/start/weather/ちくわ/豊橋市
上記例は、「豊橋市」で「ちくわ」を購入した人がいた、を想定したURLです。
実行後の画面は以下の通りです。
プロダクションに流れたメッセージを確認します。
管理ポータル > [Interoperability] > [構成] > [プロダクション] の画面で、名称をクリックします。
画面右側で「メッセージ」タブを選択し、ヘッダ欄にある番号をクリックします。もし表示されていない場合はブラウザをリロードします。
トレース画面を利用すると、コンポーネント間を送受信したメッセージの情報を確認できます。水色の枠の部分では、Web API から気象情報を取得して返送していることがわかります。
このように、トレースを利用すると、その時どんな順序でどんなデータが送受信されていたのかを確認できます。
この記事を通して、プロダクションにはシステム統合に必要なコンポーネントとその設定が定義されていることを サンプルコードの設定を参照しながら確認できました。
また、トレース画面を利用することでプロダクションに流れるメッセージの詳細を時系列に参照できることも確認できました。
この後の記事では、このトレースに表示されている「メッセージ」を作成するときの考え方や、実際の定義方法を解説します。
記事
Hiroshi Sato · 2021年11月24日
これは InterSystems FAQ サイトの記事です。
InterSystems製品開始時に、OSの実行ファイルやコマンド、InterSystems製品内に作成したプログラムを実行したい場合は SYSTEM^%ZSTART ルーチンに処理を記述します。
(%ZSTARTルーチンは%SYSネームスペースで作成します)
SYSTEM^%ZSTART に記述する処理は、事前にあらゆる条件下でうまく動作することを確認してください。
^%ZSTART ルーチンの記述ミスや、記述は正しくとも起動時にコマンドが応答を返さなかったり処理でエラーが起こった場合、InterSystems製品が起動できなくなることがあります。
詳しくは、以下ドキュメントをご参照ください。
%ZSTART、%ZSTOPルーチンの記述について【IRIS】%ZSTART、%ZSTOPルーチンの記述について
お知らせ
Toshihiko Minamoto · 2021年6月22日
開発者コミュニティの皆さん、こんにちは。
Discordについてはご存知の方も多いと思いますし、実際にチャットされている方も多いと思います。開発者のソーシャルクラブに参加いただき、ぜひインターシステムズの技術をより身近なものにしてください!
💥 InterSystems Developers Discord Channel 💥
超高速なコミュニケーション手段としてご利用ください。
開発者コミュニティDiscordサーバには、たくさんのインターシステムズに関連するチャンネルや会議、日常生活での会話のチャンネルがあります。開発者の世界をより身近なものにするため、ぜひクラブに参加してください!
では InterSystems Developers Discord でお会いしましょう✌
改善提案や、チャンネルの作成等、皆さんのお考えやコメントをご遠慮なくお寄せください。
お知らせ
Toshihiko Minamoto · 2022年3月4日
InterSystems Product Alerts and Advisories page に投稿された14件の勧告へのリンクです。HealthShare製品は全て、IRIS for Healthは最初の3件について影響があります。
FHIR Search with an Assigning Authority but no Identifier Omits Results
Some FHIR Queries that use _include and _revinclude Fail Silently
FHIR Queries May Omit Results
FHIR Queries that Specify a Quantity but no Units of Measure Return Incorrect Results
Time Zone Offsets not Applied to FHIR Resources
FHIR Searches that Specify a Time Range may Improperly Include or Exclude some Data
Clinical Viewer may lose “Standard Types” on Upgrade
Cross-site Scripting Issue in the Clinical Viewer
MPI Demographics May Contain Unconsented Data
When No Consent Group is Specified, Clinical Consent Rules May Fail
HS.Stream Global in Edge Gateways Not Cleared After Errors
HealthShare Care Community Tasks can be Assigned to Members of a Care Team who do not have Permission to View or Take Action on them
Cross-site Scripting Vulnerability in HealthShare Patient Index
Medications with a Blank “Start Date” may not Display in the Clinical Viewer
お知らせ
Toshihiko Minamoto · 2023年4月18日
インターシステムズは、InterSystems IRIS、InterSystems IRIS for Health、HealthShare Health Connect 2022.1.3 のメンテナンスリリースを公開しましたのでお知らせします。このリリースでは、これまでの2022.1.xリリースに対して厳選された機能とバグフィックスが提供されます。
変更点についての追加情報は、これらのページでご覧いただけます
InterSystems IRIS
InterSystems IRIS for Health
HealthShare Health Connect
より良い製品にするため、開発者コミュニティにご意見をお寄せください。
ソフトウェアの入手方法
本ソフトウェアは、古典的なインストールパッケージとコンテナイメージの両方が利用可能です。 利用可能なインストーラとコンテナ・イメージの詳細なリストについては、「サポート対象プラットホーム」を参照してください。
InterSystems IRISとInterSystems IRIS for Healthのインストール・パッケージは、このWRCのInterSystems IRIS Data Platform Full Kits のページから入手できます。 HealthShare Health Connectキットは、WRCのHealthShare Full Kitsのページから入手できます。
コンテナ・イメージは、InterSystems Container Registryから入手できます。
このリリースには、Community Editionのキットやコンテナはありません。
このリリースに含まれるすべてのキットおよびコンテナの番号は、2022.1.3.668.0 です。
記事
Mihoko Iijima · 2020年4月28日
この連載記事では、InterSystemsの技術とGitLabを使用したソフトウェア開発に向けて実現可能な複数の手法を紹介し、議論したいと思います。 次のようなトピックについて説明します。
第1回
Gitの基本、Gitの概念を高度に理解することが現代のソフトウェア開発にとって重要である理由
Gitを使用してソフトウェアを開発する方法(Gitのフロー)
第2回
GitLabワークフロー - アイデアからユーザーフィードバックまでの完全なソフトウェアライフサイクルプロセス。
継続的デリバリー - チームが短いサイクルでソフトウェアを作成し、ソフトウェアをいつでも確実にリリースできるようにするソフトウェアエンジニアリング手法です。 この手法はソフトウェアの構築、テスト、リリースをより速く、より頻繁に行うことを目指しています。
第3回
GitLabのインストールと構成
利用環境のGitLabへの接続
第4回
継続的デリバリーの構成
第5回
コンテナとその使用方法(および使用する理由)。
第6回
コンテナを使用した継続的デリバリーパイプラインの主要コンポーネント
それらすべての連携方法。
第7回
コンテナを使用した継続的デリバリーの構成
第8回
InterSystems Cloud Managerを使用した継続的デリバリーの構成
第9回
コンテナアーキテクチャ
この連載記事では、継続的デリバリーの一般的な手法について説明しました。 これは非常に広範なトピックであり、この連載記事の内容は完成されたものではなく、レシピを集めたものとして考えてください。 アプリケーションのビルド、テスト、配信を自動化したい場合、一般的には継続的デリバリー、特にGitLabが最適です。 継続的デリバリーとコンテナを使えば、必要に応じてワークフローをカスタマイズできます。