検索

クリアフィルター
記事
Mihoko Iijima · 2021年8月11日

パフォーマンス低下時の情報収集ツールについて

これは InterSystems FAQ サイトの記事です。 以下のような情報収集ツールがあります。 1) 性能評価の為のツール GLOSTAT グローバルアクセスのカウンター情報 mgstat グローバルアクセスのカウンター情報を連続してファイルに記録する JOBEXAM 問題のあるプロセスをモニターする SystemCheck または Buttons 内部情報の収集 使用方法詳細は以下の記事もご参照ください。 【IRISベース】トラブル発生時の情報収集方法(IRIS / IRIS for Health / UCR 編) 【Caché ベース】トラブル発生時の情報収集方法(Caché / Ensemble / HealthConnect 編) PERFMON グローバル、ルーチン、プロセス毎のグローバルアクセスカウンタ情報 収集例は添付のPDFをご参照ください PERFMON に用意された関数名を利用して、PERFMON で収集したデータをファイル出力するサンプルプログラムもご用意しています。 https://github.com/Intersystems-jp/FAQ-ZPERFMON PROFILE アプリケーションのルーチンおよびクラスのパフォーマンス解析(ルーチン単位に消費CPU、グローバル参照など取得可能) %SYS.MONLBL 特定のルーチンを行単位でパフォーマンス解析(処理時間など行単位に計測) 詳細については、以下ドキュメントをご参照下さい。 ^GLOSTAT を使用したグローバル動作の統計収集について【IRIS】 ^GLOSTAT を使用したグローバル動作の統計収集について ^PERFMON を使用したシステム・パフォーマンスの監視について【IRIS】 ^PERFMON を使用したシステム・パフォーマンスの監視について ^PROFILE を使用したルーチン・パフォーマンスの監視について【IRIS】 ^PROFILE を使用したルーチン・パフォーマンスの監視について ※PROFILEは、Caché2009.1で追加されたシステムルーチンです。 ^%SYS.MONLBL を使用したルーチン・パフォーマンスの検証について【IRIS】 ^%SYS.MONLBL を使用したルーチン・パフォーマンスの検証について ^mgstat を使用したパフォーマンスの監視について【IRIS】 ^mgstat を使用したパフォーマンスの監視について 2) Windowsのパフォーマンスモニター インターシステムズのユーティリティでありませんが、CPU、メモリ、ディスクI/O のどれがパーフォマンスのボトルネックになっているのかを特定する為に使用します。 使用方法については、「パフォーマンス調査ガイド ~知っておこう システムの基準値~」の P35~38 をご参照ください。 3) 情報収集例 パフォーマンス低下時に、1) でご紹介した mgstat と 2) の情報収集を行います。 1) の mgstat により、データベースに対するアクセス量が取得でき、2) によりパフォーマンス低下時、コンピュータのどの資源が不足しているかの判別の材料になります。 さらに必要であれば、1) のPERFMONの情報収集を行い 、これによりアクセスの多いグローバル、ルーチンの情報が取得できます。 特定のルーチンに対するパフォーマンス解析では、以下2つのルーチンを利用します。 ルーチンのCPU使用率、グローバル参照数、処理時間など計測する場合は PROFILE 行単位でパフォーマンス解析(処理時間の計測など)を行う場合は %SYS.MONLBL ご利用状況に合わせて、ご使用ください。
記事
Toshihiko Minamoto · 2022年4月12日

ビジュアルトレースと選択の自由

コミュニティの皆さん、こんにちは。お元気ですか? 皆さんは、創造性をどのようにして発揮していますか? 新しいアイデアはどのようにしてテストしていますか? 数年にもわたって、私はずっと新しいものを作り出し、既存のものを改良し、実験、テスト、破壊(いつも壊れてしまいます)を経て作り直し、そしてこのプロセスを繰り返してきました。 InterSystems が推進するコンテストは、モチベーションを大きく持ち上げてくれます。もちろん、賞品に目が行ってしまうことは否定できませんが。 しかし、賞品や報酬だけでなく、こういったコンテストでは自分の創造性が試されますし、作成、改良、テスト、実験の機会が得られます。 さらに、最も素晴らしいのは、何をやるのも自由であるということです! 私の場合、こういった機会は、独自の [ホワット・イフ...?](https://en.wikipedia.org/wiki/What_If...%3F_(TV_series))(マーベルが作家に自由にストーリーを改良させるシリーズ)を作成できるチャンスと見なしているため、これらのアイデアを私と一緒に受け入れてくれる人がいたのは幸運でした![laugh](https://pt.community.intersystems.com/sites/all/libraries/ckeditor/plugins/smiley/images/teeth_smile.png "laugh") @José.Pereira に感謝です。 前回の相互運用性コンテストでは [Message Viewer](https://openexchange.intersystems.com/package/IRIS-Interoperability-Message-Viewer?tab=details) を作成したのですが、今回の相互運用性コンテストでも Message Viewer をもう一度取り上げました。_ただし_、**独自のビジュアルトレース機能**を追加して、です! InterSystems テクノロジーを使用しており、統合機能の部分(Ensemble/Interoperability)をご存知の方であれば誰でも、ビジュアルトレース機能は長い間、同じ状態のまま、問題なく存在していたことをご存知でしょう。 確かに機能しますし、メッセージのシーケンス図や詳細を表示して情報や XML を引き出したりできますが、 機能するからと言って、改善しない理由はありませんよね? 新しい視点をもたらし、ちょっとした変化を促進してもよいのではないでしょうか? 例として、Steve Rogers がいます。マーベルの主人公の 1 人であるキャプテン・アメリカですが、ペギー・カーターをキャプテンとして再構想、制作、テストしました😂 それでは、私たちが作った新しい「ペギー・カーター」、つまりビジュアルトレースについて少しお話ししましょう!  古き良きビジュアルトレースを以下に示します。 ![](/sites/default/files/inline/images/images/screen_shot_2021-10-21_at_07_29_35.png) さて、ここに数千件ものメッセージがあり、単純なメッセージを簡単に再送できない状態であることを想像してみてください。 メッセージビューア画面に戻り、メッセージを掘り起こしながら、検索して再送信する必要があるでしょう。 ![](/sites/default/files/inline/images/images/screen_shot_2021-10-21_at_07_30_03.png) そこで、新しい外観で情報を集めて単純な機能を提供することで、これが可能であることを示すことを考えました。開発者の日常業務が少しでも楽になると思います。 ![](/sites/default/files/inline/images/images/newmessagevisualtrace.png) **デモ** このアプリを気に入ってもらえて、投票する価値があると思ってくれたなら、**IRIS Message Viewer** に投票してください!  
記事
Megumi Kakechi · 2022年9月9日

データベースをバックアップする際の停止時間をできるだけ短くしたいとき

これは InterSystems FAQ サイトの記事です。外部バックアップ機能と、SANソリューションが提供するスナップショット(スナップクローン、ミラークローンなど呼び方はベンダ毎に異なります)などのテクノロジを利用することで、バックアップ時のインスタンス停止時間を最短にすることができます。 操作手順概要は以下の通りです。 外部バックアップ用ユーティリティを利用して、データベースファイルへの書き込みを一時中断します(%SYSネームスペースで実行します)。 %SYS>set status=##class(Backup.General).ExternalFreeze() 外部のスナップショットユーティリティを使用して、ファイルシステムのスナップショットを作成します。 データベースファイルへの書き込みを再開するため、外部バックアップ用ユーティリティを使用します。 %SYS>set status=##class(Backup.General).ExternalThaw() バックアップメディアにスナップショットをコピーします。 【ご参考】ExternalFreeze() の処理は以下のようになります。 1. ジャーナルファイルの切り替え 2. データベースバッファ上の書き込み待ちバッファをすべてデータベースファイルに書き出す 3. ライトデーモンをサスペンド状態にする これらの処理の後、データベースファイルは静的な状態になり、外部のバックアップ処理によるバックアップが可能な状態(※)になります。※スナップショットコピーやミラーコピーの同期完了状態で切り離しが可能な状態。 この処理では、グローバルに対する書き込みを禁止していない為、データベースへの書き込みアクセスは、データベースキャッシュのバッファに余裕があれば可能です。ただし、ExternalFreeze() によるライトデーモンの不活動が長時間の場合、以下の条件で書き込みアクセスが待ち状態になります。 (1) 書き込み待ちのバッファ数が全バッファ数の70%以上になった場合 (2) ライトデーモンの不活動時間が10分以上(既定値)になった場合 (2)について、ライトデーモンの不活動時間のタイムアウト値は既定値で10分となっています。ExternalFreeze() が10分以上続く場合、ExternalThaw() が実施されるまで、書き込みアクセスが待ち状態になります。このライトデーモンの不活動時間のタイムアウト値は、ExternalFreeze() の第7パラメータにてsec単位で指定可能です。このタイムアウト値の範囲は、120秒~1200秒になります。 実行例: %SYS>s x=##class(Backup.General).ExternalFreeze(,,,,,,1200) ;タイムアウト値 20分 外部バックアップについての詳細は、以下のドキュメントをご覧ください。外部バックアップについて 各バックアップ方法については、以下の関連トピックをご覧ください。 【関連トピック】データベースのバックアップ方法について累積バックアップと差分バックアップの違いについて稼働中のインスタンスを停止せずにバックアップを行う方法データベースのバックアップについて(InterSystems Symposia 2014)VM Backups and Caché freeze/thaw scripts
記事
Megumi Kakechi · 2025年7月15日

IRISのプロセス(処理)を停止させる方法

これは InterSystems FAQ サイトの記事です。IRISのプロセスを終了したい場合、管理ポータルから行う方法と、ターミナルからユーティリティやコマンドを使用して行う方法があります。 こちらのトピックでは、以下の3つの方法で停止する方法をご紹介します。 【プロセスの停止方法】 1.管理ポータルから停止する方法 2.ユーティリティーで停止する方法(RESJOB、JOBEXAM) 3.プログラムで停止する方法 【注意】IRIS外から(Windowsならタスクマネージャーなど)、プロセスの終了は絶対に行わないでください。IRIS外からプロセス終了してしまうと、IRIS内部ではプロセスの削除を検知できなかったりすることで、IRISの動作が不安定になったり、システム全体がハングする危険性がありますので、ご注意ください。 外部から停止の例外が一つだけあります。$ZF コマンドによって起動された子プロセスが、何らかの問題で応答を返さなかった場合、$ZF コマンドを実行した親プロセスはそのまま残り続けます。そのような親プロセスを終了したい場合、通常の上記1~3の方法では停止できません。その際は、先に外部から子プロセスを停止する必要があります。子プロセスを特定するためには、以下の方法があります。 例:Windowsの場合 1. process explorer(マイクロソフト製) 2. PowerShell コマンド PS>wmic Process where '(parentprocessid=10188)' get 'processid,executablepath' では、以下に通常のプロセスを停止する方法をご紹介します。 1.管理ポータルから停止する方法 システムオペレーション > プロセスよりプロセス一覧を表示し、終了したいプロセスの 詳細 リンクをクリックし、詳細ページを開きます。 終了ボタンをクリックすると、モーダルダイアログが開くので、終了ボタンを押してプロセスを終了します。 2.ユーティリティーで停止する方法(RESJOB、JOBEXAM) 管理者権限でターミナルにログインし、ユーティリティを実行します。 ★RESJOB USER>zn "%SYS" %SYS>do ^RESJOB Force a process to quit InterSystems IRIS Process ID (? for status report): 56528 // 終了したいプロセスIDを入力+Enter で終了する Process ID (? for status report): // Enter で抜ける( ? を入れるとプロセス一覧が表示される) %SYS> ★JOBEXAM %SYS>do ^JOBEXAM IRIS for Windows (x86-64) 2025.1 (Build 225_1U) Job# NSpace Routine Commands Globals State PID Current device 1 CONTROL 0 0 RUNW 66824 2 WRTDMN 26 357 RUNW 18340 3 GARCOL 0 0 RUNW 48172 4 JRNDMN 156 25 RUNW 44180 5 EXPDMN 0 0 RUNW 46292 6 %SYS %SYS.WorkQueueMgr133834 13242 SEMW 42112 //./nul 7 %SYS MONITOR 31238 78 EVTW 62572 //./nul 8 %SYS CLNDMN 0 21 RUNW 58484 //./nul 9 %SYS LMFMON 1587 80 EVTW 17168 //./nul 10 %SYS RECEIVE 795 97 HANGW 17212 //./nul 11 USER shell 362 37 READ 41016 |TRM|:|41016 // これを終了する場合 12 %SYS %SYS.WorkQueueMgr 77088 7396 EVTW 3848 //./nul 13 %SYS %SYS.SERVER 0 17 READ 48840 1972: 14 %SYS %SYS.TaskSuper 2073 135 EVTW 22480 //./nul 15 %SYS SYS.VSSWriter 0 14 RUNW 6884 //./nul 16 %SYS %SYS.Monitor.Co<5697596 2242094 EVTW 26840 //./nul 17 %SYS %SYS.WorkQueueMgr 4763 156 SEMW 39616 //./nul 19 %SYS %SYS.sqlcq.uEidd<133559 1338 RUN 37884 |TRM|:|37884 (N)ext,(P)rev,(G)oto,(E)xamine,(T)erminate,(S)uspend,(R)esume,(Q)uit => // T 押下(Terminate) Terminate: Enter Job # or "P" followed by the PID: P41016 // P+プロセスID または Job番号を入力+Enter : Job Terminated でプロセスが終了する 3.プログラムで停止する方法 USER>zn "%SYS" %SYS>do $SYSTEM.Process.Terminate(17456) // ^RESJOB ユーティリティと同じ。プロセスIDを指定して終了する %SYS> %SYS>do $SYSTEM.Process.Terminate() // 自分自身(現在の)プロセスを終了する場合
記事
Toshihiko Minamoto · 2021年6月3日

コンテナ - コンテナとは?

## コンテナ [InterSystems IRIS Data Platformの公開](https://community.intersystems.com/post/intersystems-iris-data-platform-201810-release)により、Dockerコンテナでも製品を提供しています。 コンテナとは一体何でしょうか。 基本的なコンテナの定義は、プロセスのサンドボックスの定義です。   コンテナは、たとえば実行できるという点において、仮想マシン(VM)に似た部分を持つソフトウェア定義パッケージです。  コンテナは、完全なOSエミュレーションを使わずに分離することができるため、 VMよりもはるかに軽量です。  本質的に、コンテナは、どのようにアプリケーションをシステムから別のシステムに確実に移動し、それが動作することを保証できるのかという問題に対する答えと言えます。 アプリケーションのすべての依存関係をコンテナにカプセル化し、プロセス分離領域を作成することにより、アプリケーションソリューションがプラットフォーム間で移動した場合でも動作するという高い保証を得ることができます。   プロセスは、オペレーティングシステムによって実行が可能です。 これらのプロセスはアドレス領域、ネームスペース、cgroupなどを共有し、通常、OSの環境全体にアクセスすることができます。それらのスケジュールと管理は、OSが行います。 すべて良いことではありますが、特定のプロセスやいくつかのプロセスを分離して、特定のタスクや演算、またはサービスを実行したい場合はどうでしょうか。 手短に言えば、プロセスを分離できる機能こそ、コンテナが提供している機能なのです。 したがって、コンテナをプロセスのサンドボックスとして定義することができるでしょう。  では、サンドボックスとは何でしょうか。 サンドボックスは、コンテナがプロセスを持つ分離レベルです。 この機能は、ネットワークインターフェース、マウントポイント、インタープロセス通信(IPC)、ユニバーサルタイムシェアリング(UTS)といったシステムのほかの重要な部分もサンドボックス化することのできるネームスペースと呼ばれるLinuxのカーネル機能により実装されています()。  コンテナまたはサンドボックスは、制御グループまたはcgroupと呼ばれる別のカーネル機能によっても管理または制御することができます()。 コンテナがほかのコンテナやホストとリソースを共有する上で、ほかのネイバーに害を与えないように、コンテナにルールが適用されます。  コンテナとVMの違いを理解するには、VMを_家_に、そしてコンテナを_マンション_に例えることができます。   ![](/sites/default/files/inline/images/containersapartments.jpg) VMは、一軒家のように、自己完結型で独立しています。 それぞれの家には、配管、暖房、電気といった固有のインフラストラクチャが備わっており、 最低要件も与えられています(最低、寝室は1室、屋根は1つなど)。  一方のコンテナは、共有のインフラストラクチャを使用するように作られているため、マンションとして捉えることができます。 マンションの建物は、配管、暖房、電機システム、正面玄関、エレベーターなどを共有していますが、これと同様に、コンテナも、Linuxカーネルを通じてホストが提供しているリソースを使用します。 また、マンションの各居住戸のサイズや形には様々なものがあることも考えましょう。  コンテナには完全なOSはなく、/binの実行可能ファイルや /etcの構成ファイルと定義ファイルといった、最小限必要なLinux OSしか備わっていないため、サイズが非常に小さくなります。そのため、その場所を移動したり、スピンアップする場合に、一秒きっかりで敏速に行うことができます。  コンテナを構築した瞬間から、ソフトウェアファクトリーのプロビジョニングパイプラインを通じ、本番環境での最終実行に至るまで、アジリティを得られることになります。 ちなみに、コンテナはCI/CDマイクロサービスアーキテクチャのコンテキストにピッタリと収まりますが、これはまた別の機会にお話ししましょう。 コンテナ内のプロセスは、コンテナのライフサイクルと密接な関係があり、 コンテナを_起動_すれば、アプリのすべてのサービスも起動して実行し(たとえば、あるWebサーバーコンテナのポート80と、InterSystems IRISコンテナのポート57772と1972)、 コンテナを_停止_すれば、すべてのプロセスも停止します。  この記事では、コンテナのランタイムの基本的な概念について説明しました。コンテナは、プロセスをホストやその他のコンテナから分離するサンドボックスです。  コンテナを理解するには、その[イメージ](https://community.intersystems.com/post/container-what-container-image)に関する別の側面もあります。 これについては、第2部の記事で説明することにします。
記事
Megumi Kakechi · 2022年8月30日

各アクセス方法(ダイレクト/SQL/オブジェクトアクセス)による速度の違いについて

これは InterSystems FAQ サイトの記事です。InterSystems IRIS Data Platform(以下IRISと表記)ではマルチモデルのサポートにより、データに対して様々なアクセス手法を使用することができます。 主だったアクセス手法としてダイレクトアクセス、SQLアクセス、オブジェクトアクセスがあります。 ダイレクトアクセス は、IRISのネイティブ構造であるグローバルと呼ばれるキーバリュー型のデータに直接アクセスする方法です。 SQLアクセス は、リレーショナルデータベースシステムにアクセスするための標準言語であるSQLを使用してデータにアクセスする方法です。 オブジェクトアクセス は、オブジェクト指向言語でオブジェクトを操作するための表記法として幅広く利用されるドット記法を使用してデータにアクセスする方法です。 ダイレクトアクセスとSQLアクセスおよびオブジェクトアクセスでは、処理の抽象度が異なります。 抽象度が高くなるに伴い、内部的な処理のオーバヘッドが増加するため、単純な1スレッド単位でのアクセススピードの速さについては、ダイレクトアクセスが、SQLアクセスとオブジェクトアクセスに比較して速い場合が多いです。 しかしながら、今後SQLアクセスに関してより高速に処理できるよう様々な開発が進行中です。 その点を考慮すると段々とその性能差が縮小していくことが期待できます。 一方で、IRISではマルチコア、マルチCPU環境またはシャーディング機能を利用することでSQLクエリーを並列実行する機能があるので、並列実行が効力を発揮するケースでは、ダイレクトアクセスで処理するより、圧倒的に高速に処理できる(集計処理など)場合があります。 オブジェクトアクセスとSQLアクセスでは、条件次第で、どちらが速いとは一概に言えませんが、一般的にはSQLで処理するほうが高速です。  クエリー処理に関しては、オブジェクトアクセスではなくSQLで実装することが一般的です。 またアクセススピードの違いには、使用するプログラミング言語の違いによる影響もあります。 全てのアクセス手法においてネイティブなプログラム言語であるObjectScriptでコードを記述するのが最速であるケースが多いです。 JDBCやODBC等を使用したSQL、オブジェクトアクセスの場合には、ObjectScriptでデータベースに直接アクセスするのに比しネットワーク層を介する分オーバーヘッドが大きくなり、大量にデータをアクセスする際には処理時間に大きな差が発生します。 しかしながら他のプログラム言語でのアクセスもObjectScriptでのアクセスに比して遜色のない性能が出るように製品の改良を続けていきますので、その差は少なくなっていくことが期待できます。 速度を比較する際、異なるアクセス手法に対して、条件を同じにすることは、非常に難しいことです。 あるいは、単純な速度比較は無意味なケースもあります。 アクセススピードを考える時には、以下の視点が必要です。 例えば、データの入力処理を考えてみると、データ登録前に入力データの妥当性チェックが必要となります。 オブジェクトアクセスとSQLアクセスでは、データ保存処理時、システムによる型に基づく妥当性チェックを自動的に行います。 一方、ダイレクトアクセスでは、開発者が自分で、その処理用コードを追加する必要があります。 また、オブジェクト間に複雑な関連がある場合、オブジェクトアクセスの場合は、システムがその複雑さを理解しながら、適切に処理してくれるのに対して、SQLアクセスの場合は、処理単位が行単位のため、関連は開発者が自分で処理しなければならないケースもでてきます。 これらの事と、処理スピードとは、基本的に逆の相関関係にあり、何らかのトレードオフがつきものです。 以上のことを踏まえ、どちらを優先するか考えながら適切なアクセス手法を選択することをお勧めします。(繰り返しになりますが、マルチコア、マルチCPU、シャーディング環境では、クエリー処理に関してSQLで処理することで高速に処理できる可能性が高まります。) さらに、InterSystems製品のメリットは、各種アクセス手法を適宜使い分けることにより、アプリケーション開発を最適化できる点にあることを、ご理解いただけたら幸いです。
記事
Hiroshi Sato · 2020年11月16日

ネームスペースやデータベースを作成するコマンドラインインタフェースとAPI

これはInterSystems FAQ サイトの記事です。 Config.Configurationクラス、SYS.Databaseクラスのメソッドを使用して、ネームスペース・データベースの作成及び登録をターミナルから実行することができます。 以下はデータベースファル/CacheDB/AAA/cache.datを作成し、構成ファイル(cache.cpf)にデータベース AAA、及び、ネームスペースAAAの登録を行う一連の実行例です。*実行は、%SYSネームスペースで行って下さい。* Set Directory="/CacheDB/AAA/"Set x=$ZF(-100, "/shell", "mkdir", Directory)Set db=##Class(SYS.Database).%New()Set db.Directory=DirectorySet status=db.%Save()Set DBName="AAA"Set status=##class(Config.Configuration).AddDatabase(DBName,Directory)Set NSName=DBNameSet status=##class(Config.Configuration).AddNamespace(NSName,DBName) リモートデータベースからネームスペースを作成する場合は、以下のデータベース定義で、第三パラメータにリモートのサーバ名を指定します。 Set status=##class(Config.Configuration).AddDatabase(DBName,Directory,Server) ※クラスの詳細については、それぞれのクラスリファレンスをご参照下さい。 また、データベースの作成・登録については、^DATABASEルーチンを使用することも可能です。 このルーチンを実行すると、下記のようにオプションが表示されますので、目的によって選択します。 以下は、データベース作成の実行例です。*実行は、%SYSネームスペースで行って下さい。* %SYS>do ^DATABASE 1) Create a database2) Edit a database3) List databases4) Delete a database5) Mount a database6) Dismount a database7) Compact a database8) Show free space for a database9) Show details for a database10) Recreate a database11) Manage database encryptionOption? 1Database directory? D:\200820DS\Mgr\TEST2Directory does not exist, create it? No => yChange default database properties? No =>Dataset name of this database in the configuration: TEST2Mount TEST2 Required At Startup? No => yConfirm creation of database in d:\200820ds\mgr\test2\? Yes => yFormatting...Database in d:\200820ds\mgr\test2\ createdDataset TEST2 added to the current configuration.Database directory? ※^DATABASEルーチンの各オプションについては、以下ドキュメントページをご参照ください。 ^DATABASEについて【IRIS】^DATABASEについて
記事
Mihoko Iijima · 2021年2月12日

SQL から ObjectScript で記述したプログラムを実行して値を返す方法

これは InterSystems FAQ サイトの記事です。 以下例のクラスメソッド getLatestID() のように ObjectScript のクラスメソッドを用意します。返したい値を戻り値に指定し、SQLストアドプロシージャ(SqlProc)キーワードを指定するだけで値が返せます。 ClassMethod getLatestID() As %Integer [ SqlName = getLatestID, SqlProc ] { set latestID=$Order(^ISJ.TestClass1D(""),-1) quit latestID } 操作を試す場合は、以下のクラス定義をご準備ください。 Class ISJ.TestClass1 Extends (%Persistent, %Populate) { Property name As %String; ClassMethod getLatestID() As %Integer [ SqlName = getLatestID, SqlProc ] { set latestID=$Order(^ISJ.TestClass1D(""),-1) quit latestID } } データ自動生成を行うユーティリティクラス(%Populate)を継承しているため、Populate() メソッドを実行するとテストデータが作成できます。以下の例では、10件の ISJ.TestClass1 クラスに対応するデータを作成しています。 (USER ネームスペースに上記クラスを定義した状態での実行例) USER>do ##class(ISJ.TestClass1).Populate(10) 作成したクラスメソッドをストアド関数として実行している例は以下の通りです。 (ターミナルをSQLの実行環境に変更してから SELECT文を実行している例です) USER>do $system.SQL.Shell() SQL Command Line Shell ---------------------------------------------------- The command prefix is currently set to: <<nothing>>. Enter <command>, 'q' to quit, '?' for help. [SQL]USER>>select ISJ.getLatestID() As LatestID 1. select ISJ.getLatestID() As LatestID LatestID 10 1 Rows(s) Affected statement prepare time(s)/globals/cmds/disk: 0.0545s/33171/145091/8ms execute time(s)/globals/cmds/disk: 0.0003s/1/415/0ms cached query class: %sqlcq.USER.cls30 --------------------------------------------------------------------------- [SQL]USER>>select ID from ISJ.TestClass1 2. select ID from ISJ.TestClass1 ID 1 2 3 4 5 6 7 8 9 10 10 Rows(s) Affected statement prepare time(s)/globals/cmds/disk: 0.0481s/33891/148856/0ms execute time(s)/globals/cmds/disk: 0.0003s/11/887/0ms cached query class: %sqlcq.USER.cls31 --------------------------------------------------------------------------- [SQL]USER>> また、以下実行例のように記述すると、最新 ID の name だけ表示します。 select name from ISJ.TestClass1 WHERE ID=ISJ.getLatestID()
記事
Mihoko Iijima · 2021年3月26日

Linux のシェルスクリプトでルーチンやメソッドの戻り値を取得する方法

これは InterSystems FAQ サイトの記事です。 Linux で シェルスクリプト(shell script) からルーチンやメソッドを実行し戻り値を取得するには、iris コマンドを使用します。 詳細はドキュメント「インスタンスの接続について」 をご参照ください。 コマンド記述例は以下の通りです。 iris session インスタンス名 -U ネームスペース名 "実行ルーチン・メソッド" シェルスクリプトへの戻り値の指定は、ルーチンやメソッド終了時に指定する QUIT や RETURN コマンドに引数を指定する方法ではなく、プロセス処理終了時に %SYSTEM.Process クラスの Terminate() メソッドを使用して 特殊変数 $? に値を返す方法を利用します。 値は、0~255 を指定できます。 ルーチンでの利用例は以下の通りです。 // ルーチン名をTestとします start1() public {  hang 5 // 5秒待つ  //第2引数に指定した数値がシェルスクリプトに戻ります  set st=$system.Process.Terminate($JOB,11) } 実行例は以下の通りです。 # iris session iris -U USER "start1^Test()" # echo $? 11 クラスメソッドでの利用例は以下の通りです。 Class Test.Class1 { ClassMethod test() {  hang 5 // 5秒待つ  //第2引数に指定した数値が シェルスクリプトに戻ります  set st=$system.Process.Terminate($JOB,12) } } 実行例は以下の通りです。 # iris session iris -U USER "##class(Test.Class1).test()" # echo $? 12 関連情報もあります。以下、FAQサイトのトピックをご参照ください。 Windowsバッチでターミナルスクリプトを実行する方法を教えてください Windows のバッチスクリプトでIRISのルーチンやメソッドの戻り値を取得する方法を教えてください。
記事
Hiroshi Sato · 2021年10月5日

Webゲートウェイ/CSPゲートウェイの設定管理ページにどのクライアントからもアクセスできるようにする

これは InterSystems FAQ サイトの記事です。Web/CSPゲートウェイ管理ページは、通常クライアントマシンからアクセスできないように構成されています。 任意のクライアントからアクセスするためには以下の操作を行います。 Web/CSPゲートウェイ管理ページにアクセス可能なシステムからブラウザを起動し、管理ポータルにアクセスします。管理ポータル>システム管理>構成>の所でCSPゲートウェイ管理をクリックします。表示されるページの左ペインに表示されるデフォルトパラメータをクリックします。 システム管理マシンの所に*.*.*.*と入力し、設定を保存ボタンを押下げます。 しかしながら任意のクライアントから管理ページにアクセスできるようにするのはセキュリティの観点からはあまりお勧めできません。アクセスできるクライアントはなるべく限定することをお勧めします。クライアントアドレスの指定方法としては、以下のような指定形式があります。 [SYSTEM]System_Manager=190.8.7.4-6 上記の例は、以下の記述をより簡単にしたものです。 [SYSTEM]System_Manager=190.8.7.6, 190.8.7.5, 190.8.7.4 以下の例のように、ワイルドカードも使用できます。 [SYSTEM]System_Manager=190.8.7.* 詳細は、下記ドキュメントページをご参照ください。Webゲートウェイ管理ページでのセキュリティの考慮事項【IRIS】CSP ウェブゲートウェイ管理ページでのセキュリティの考慮事項
お知らせ
Hiroshi Sato · 2020年6月29日

障害対応などの製品修正の提供方法について

お客様のシステムで発生した障害に対処するための製品修正や社内のコードレビューで新たに発見された潜在的な問題に対応するための修正などは、問題の重要度(運用に支障をきたす、アプリケーションの動作に影響があるなど)に応じて、順次新しいメジャーバージョン、メンテナンスバージョンに取り込まれていきます。 一方で、新しいバージョンのリリースには所定の時間が必要ですので、そのリリース前に該当する修正だけを適用したいというご要望にお応えするためにInterSystemsではアドホックと呼んでいる応急パッチを提供することも可能です。 しかしながら、この対応はあくまでも個別の応急処置であり、その問題が対処されたバージョンがリリースされた後には、そのバージョンをご使用いただくことを推奨致します。 この様な個別対応を繰り返し行うと、システムの構成管理が複雑化し、管理上のコストが上昇し、思わぬシステムトラブルの遠因になることもあります。 特に複数のエンドユーザー様に同じソリューションを提供する様なケースでは、システムの提供時期等によりシステム構成が変わり、適用可能なオペレーティングシステム等が変化することに伴い、全ての適用パッチを見直す必要が出てくることも想定されます。
記事
Mihoko Iijima · 2021年5月28日

キーバリュー形式で Python / Node.js / Java から IRIS にアクセスできるテンプレート(グラフ構造によくある人物相関図を IRIS で表現しています)

開発者の皆さん、こんにちは🌂 今年は早い梅雨入りでした ☔ さて、新しい✨ 実行/開発環境テンプレートを作成しました。 Docker 🐳、docker-compose 、git がインストールされていれば、すぐにお試しいただけます。ぜひご利用ください! 今回は、ご存知の方が多いと思われる(?)某アニメの登場人物を使った人物相関図をテーマに【キーバリュー形式で IRIS に登録してグラフ構造で表示してみた】を体験できるテンプレートです(テンプレートは、Python/Node.js/Java からお試しいただける環境をご用意しています)。 人物相関図のイメージ 以下、今回のテーマについて、ビデオと文字でご紹介しています。最後までお付き合いいただければ幸いです!(ビデオは全体で 7 分 20 秒) 人物相関図と言えば、グラフデータベースをイメージされると思います。 IRIS はグラフデータベースではないのですが、IRIS ネイティブのデータの「グローバル」を利用することで、グラフデータベースと似たような構造を表現することができます。 IRIS の高パフォーマンスを支える 「グローバル」 は 40 年以上前(= InterSystems 創業)から InterSystems のコア技術であるデータベースとして提供されてきました。 「グローバル」 に対する操作方法は、現代のカテゴリに合わせるとしたら NoSQL データベースと言えます。 では、どのようにグラフデータベースのような構造を表現しているか?についてですが、グラフ構造は、ノードと辺から構成されていて、辺は 2 つのノードを結び付けるものです。 SNS の「友達」で考えると、ノードは「ユーザ」、辺は「友達関係」で表現できます。 テンプレートで使用している人物相関図では、ノードは「登場人物」、辺は「登場人物との関係」を表現しています。 人物相関図のノードと辺(エッジ) ノードと辺を、どのようにグローバル変数に設定しているでしょうか。 ノードは以下の通りです(配列には、画面表示に利用するノードの ID を設定し、右辺に人物名を登録しています)。 ^Relation("Eren")="主人公(エレン)" 辺(エッジ)は以下の通りです(グローバル変数の配列を利用して、登場人物 → 関係のある人 [ソース→ターゲット] を設定しています)。 主人公エレンは、アルミン、ミカサ、ジークと関係がある。を表現しています。 ^Relation("Eren","Armin")="" ^Relation("Eren","Mikasa")="" ^Relation("Eren","Zeke")="" 両者で関係がある場合は、さらに以下のような配列を追加します。 ^Relation("Mikasa")="エレンの幼馴染(ミカサ)" ^Relation("Mikasa","Armin")="" ^Relation("Mikasa","Eren")="" 実際に、IRIS サーバ側で記述する場合には、ObjectScript の SET コマンドを使用してグローバル変数を設定します。 set ^Relation("Eren")="主人公(エレン)" set ^Relation("Eren","Mikasa")="" set ^Relation("Eren","Armin")="" set ^Relation("Eren","Zeke")="" set ^Relation("Mikasa")="エレンの幼馴染(ミカサ)" set ^Relation("Mikasa","Armin")="" set ^Relation("Mikasa","Eren")="" 配列のサブスクリプト(括弧の中身)は、配列のノード(例では、第 1 番目と第 2 番目)毎に Unicode 昇順でソートされます。 実行後、管理ポータルなどからグローバル変数一覧を参照すると、実行順に関係なく Unicode 昇順にソートされていることを確認できます。 管理ポータルは、http://localhost:52779/csp/sys/UtilHome.csp でアクセスできます(ユーザ名:_system 、パスワード:SYS)。 ※ポート番号はご利用環境に合わせてご変更ください。 管理ポータル > [システムエクスプローラ] > [グローバル] > 左画面で「ネームスペース」USER を選択 > ^Relation の「表示」をクリック ここまでご紹介したグローバル変数に対する各言語のコード例については、テンプレート用リポジトリの以下サブディレクトリをご参照ください。 👉 https://github.com/Intersystems-jp/IRIS-NativeAPI-Template Python :jupyter のコンテナを用意します(Jupyter は 8896 ポートでアクセスできます)。 Node.js:Node 12 のコンテナを用意します(8080 ポートで確認用 Web ページを参照できます)。 Java:OpenJDK 8 のコンテナを用意します。 1) テンプレートの処理概要 各言語ごとのシンプルなコード例とコンテナで提供している内容についての解説は、以下のビデオでもご紹介しています(全体で 9 分 20 秒)。 テンプレートでは、Python / Node.js / Java 用から IRIS 用コンテナへ、キーバリュー形式でのアクセスを行うため、Native API を使用しています。 各言語で必要な irisnative モジュールを使用するための手順は、言語ごとのサブディレクトリで解説しています。 Python Node.js Java ビデオでもご紹介していますが、シンプルなコード例は以下の通りです。 Python の例 #irisnativeモジュールインポート import irisnative #IRISに接続 (ホスト名,スーパーサーバポート番号,ネームスペース,ユーザ,パスワード) connection = irisnative.createConnection("iris",1972,"user","_system","SYS") #IRISインスタンス生成 iris_native = irisnative.createIris(connection) #値設定 iris_native.set("鎧の巨人\n(ライナー)","Relation","Reiner") iris_native.set("超大型の巨人\n(ベルトルト)","Relation","Bertolt") iris_native.set(None,"Relation","Reiner","Bertolt") iris_native.set(None,"Relation","Bertolt","Reiner") #Iterator() for source,value in iris_native.iterator("Relation").items(): print(source,"-",value) for target,value in iris_native.iterator("Relation",source).items(): print(" 関係者:",target) connection.close() Node.js の例 const irisnativeapi = require('intersystems-iris-native'); //接続 let connectionInfo = {"host": "nativeapi-iris","port": 1972,"ns":"USER","user":"_SYSTEM","pwd":"SYS"}; const connection = irisnativeapi.createConnection(connectionInfo); //IRISインスタンス生成 const irisNative = connection.createIris(); //値設定 irisNative.set("鎧の巨人(ライナー)","Relation","Reiner"); irisNative.set("超大型の巨人(ベルトルト)","Relation","Bertolt"); irisNative.set(null,"Relation","Reiner","Bertolt"); irisNative.set(null,"Relation","Bertolt","Reiner"); let ite1=irisNative.iterator("Relation"); //Iterator() for ([source,data] of ite1) { console.log("source"+"-"+data); let ite2=irisNative.iterator("Relation",source); for ([target] of ite2) { console.log(" 関係者:",target); } } connection.close(); 【Java の例】 package NativeAPI; import com.intersystems.jdbc.IRIS; import com.intersystems.jdbc.IRISConnection; import com.intersystems.jdbc.IRISDataSource; import com.intersystems.jdbc.IRISIterator; public class Test{ public static void main (String[] args) { try { //接続オープンには IRISDataSourceを使う IRISDataSource ds = new IRISDataSource(); // jdbc:IRIS://ホスト名:スーパーサーバポート/ネームスペース名 ds.setURL("jdbc:IRIS://localhost:1972/user"); ds.setUser("_SYSTEM"); //ユーザ名 ds.setPassword("SYS"); //パスワード IRISConnection dbconnection = (IRISConnection) ds.getConnection(); //create irisNative object IRIS irisNative = IRIS.createIRIS(dbconnection); irisNative.set("鎧の巨人(ライナー)","Relation","Reiner"); irisNative.set("超大型の巨人(ベルトルト)","Relation","Bertolt"); irisNative.set("","Relation","Reiner","Bertolt"); irisNative.set("","Relation","Bertolt","Reiner"); IRISIterator character=irisNative.getIRISIterator("Relation"); while (character.hasNext()) { String source=character.next(); System.out.println("\n人物 = "+ source + " - 説明:"+ character.getValue()); //関係のある人を表示(^Relation) IRISIterator correlate=irisNative.getIRISIterator("Relation",source); while (correlate.hasNext()) { String target=correlate.next(); System.out.println(" 関係者 : "+ target); } } //irisの接続をClose irisNative.close(); dbconnection.close(); } catch (Exception ex) { System.out.println(ex.getMessage()); } } 2) Native API について Native API は、IRIS 内部のネイティブデータ(=グローバル変数)を直接操作できる API で Python、Node.js、Java、.NET からアクセスできます。 グローバル変数の操作には、IRIS サーバーサイドプログラミングで使用する ObjectScript を利用しますが、Native API を利用することで、ObjectScript を使用せずにお好みの言語からアクセスすることができます。 また、Native API は、グローバル変数の設定/取得の他にも、クラスメソッド、ルーチン、関数を実行することができます。 3) テンプレートの使用方法 言語ごとのサブディレクトリにある README をご参照ください。 Python Node.js Java テンプレートの例に使用した某アニメの人物相関図ですが、実は完成していません。 あの登場人物がいない!とお気づきの方、ぜひ追加いただき、よろしければ記事の返信欄に貼り付けていただければ・・。 最後までお読みいただきありがとうございました! 関連記事(NoSQLをテーマにした詳細説明付き記事):Python Native APIでNoSQLデータベースにアクセス
記事
Toshihiko Minamoto · 2023年4月26日

2022.3 のカラムナーストレージ

[Global Summit 2022](https://learning.intersystems.com/course/view.php?id=2077) または [2022.2 ローンチウェビナー](https://www.intersystems.com/resources/whats-new-in-intersystems-iris-2022-2/)の内容からよく覚えていると思いますが、InterSystems IRIS の分析ソリューションに組み込むための目覚ましい新機能をリリースしようとしています。 分析クエリを桁違いに高速化する、代替の SQL テーブルデータ格納手法である[カラムナー(列指向)ストレージ](https://learning.intersystems.com/course/view.php?id=2112)です。 もともと 2022.2 の実験的機能としてリリースされましたが、[最新の 2022.3 開発者プレビュー](https://community.intersystems.com/post/intersystems-publishes-developer-preview-5-intersystems-iris-iris-health-healthshare-health)には多数の更新が含まれているため、別途ここで簡単に説明したいと思います。 ### 簡単な要約 カラムナーストレージにあまり詳しくない方は、[こちらの簡単な紹介動画](https://learning.intersystems.com/course/view.php?id=2112)かこの件に関する [GS2022 セッション](http://learning.intersystems.com/course/view.php?id=2077)をご覧ください。 手短に言うと、新しい `$vector` データ型を用いて、列ごとに 64k チャンクでテーブルデータをエンコーディングしています。 `$vector` は、疎データと密データの両方を効率的に格納できるように、アダプティブエンコーディングスキームを利用する(現時点では)内部専用のデータ型です。 エンコーディングは、一度に 64k チャンク全体の集計、グループ化、およびフィルタを計算し、可能な場合は [SIMD 命令](https://en.wikipedia.org/wiki/Single_instruction,_multiple_data)を利用するなどの、一連の専用の `$vector` 演算にも最適化されています。  SQL クエリ時に、これらのチャンクに対しても動作するクエリプランを作成して、これらの演算を利用します。想像できるように、従来の行単位での処理に比べ、これによってクエリを実行するための IO の量と ObjectScript 命令の数が大幅に削減されます。 もちろん、行指向における単一値演算に比べれば、個別の IO はより大きく、`$vector` 演算は多少重くなりますが、非常に大きなメリットがあります。 $vector データを処理し、チャンク全体を一連の高速な個々の演算にプッシュする実行戦略を「ベクトル化された」クエリプランと呼んでいます ### とにかく速い 最も重要なのは、すべてが高速化されたことです。 列インデックスに関するオプティマイザの理解が深まったことで、リクエストされたフィールドの一部が列インデックスまたはデータマップに格納されていない場合であっても、より多くのクエリが列インデックスを使用するようになります。 また、多くのケースで列インデックスとビットマップインデックスが組み合わせられるようになります。これは、列インデックスを既存のスキーマに追加することから始める場合に役立ちます。 新しいキットには、いくつかのクエリ処理の機能強化に対する低レベルの `$vector` 演算の最適化から並列化できるより広範な一連のベクトル化されたクエリプランまで、パフォーマンスを改善する多数の変更がスタック全体に含められています。 `INSERT .. SELECT` ステートメントなどによる特定のデータ読み込み方法も インデックスの構築にすでに使用しているバッファリングされたモデルを採用し、テーブル全体を非常に高いパフォーマンスで構築できるようになっています。 ### ベクトル化された JOIN このリリースで追加された最も注目すべき機能は、ベクトル化の方法による列データの JOIN のサポートです。 2022.2 では、クエリ内で 2 つのテーブルからデータを結合する場合、列編成のデータでも行編成のデータでも機能する堅牢な行単位の JOIN 戦略に頼っていました。 今回は、JOIN の両端が列形式で格納されている場合、新しいカーネル API を使用して、メモリ内で JOIN し、`$vector` 形式を保持することができるようになっています。 これは最も複雑なクエリであっても完全にベクトル化されたクエリプランにするもう 1 つの重要なステップです。 以下に、新しい関数を利用するクエリの例を示します。[前のデモ](https://github.com/bdeboe/isc-taxi-demo)で使用した New York Taxi データセットの自己結合を行っています。 SELECT   COUNT(*),   MAX(r1.total_amount - r2.total_amount) FROM   NYTaxi.Rides r1,   NYTaxi.Rides r2 WHERE   r1.DOLocationID = r2.PULocationID   AND r1.tpep_dropoff_datetime = r2.tpep_pickup_datetime   AND r2.DOLocationID = r1.PULocationID   AND r1.passenger_count > 2   AND r2.passenger_count > 2 このクエリは、乗客が 2 人を超えるルートのペアを検索します。2 番目のルートが最初のルートが終了する時点で同時刻に開始し、2 番目のルートが最初の開始地点に戻るルートペアです。 非常に有用な分析ではありませんが、このスキーマには実際のテーブルが 1 つしかなく、複合 JOIN キーのお陰で味気なさが少し緩和されています。 このステートメントのクエリプランには、`Apply vector operation %VHASH`(複合 JOIN キーの作成用)と `Read vector-join temp-file A` などのスニペットが含まれており、新しいベクトル化された結合が機能していることを示しています。 これは、長めのクエリプランにある小さく些細なもののように聞こえるかもしれませんが、内部では多くのスマートエンジニアリングが伴っています。このようなことをただ許可せず、スキーマレイアウトに厳しい制約を課す一般的なカラムナーデータベースベンダーがかなりの数存在しますので、ぜひ一緒にこれを楽しみましょう! :-) クエリプランがその一時ファイルの読み取りを続けると、Join 後の作業にまだ行単位の処理が残っていることに気づくかもしれません。そこで... ### 今後の予定 カラムナーストレージは 2022.3 でも「実験的」となっていますが、本番対応に近づいており、間もなくマルチテーブルクエリ用の完全なエンドツーエンドベクトル化が可能になります(訳注:2023.1では本番用としてリリースされています)。 これには、先ほど述べた JOIN 後の作業、クエリオプティマイザのより幅広いサポート、カラムナーテーブルの読み込みのさらなる高速化、共有メモリサポートなどの JOIN のさらなる機能強化などが含まれます。 要するに、今こそ、2022.3 Community Edition を使用して [New York Taxi データセット](https://github.com/bdeboe/isc-taxi-demo/)を試してみる絶好の機会です(現時点では [IPM](https://openexchange.intersystems.com/package/NY-Taxi-Demo) で、または [Docker スクリプト](https://github.com/bdeboe/isc-taxi-demo)を使用)。そうすれば、2023.1 がリリースされる頃には「Run」を押すだけで済みます! カラムナーストレージを独自のデータとクエリで使用する方法について、より具体的なアドバイスに興味のある方は、私かアカウントチームに直接ご連絡ください。[Global Summit 2023](https://www.intersystems.com/gs2023/) でお会いできるかもしれません ;-)
記事
Mihoko Iijima · 2022年1月6日

IRIS ターミナルで履歴からのコマンド実行、コマンドのショートカット作成ができるのをご存知ですか?

開発者のみなさん、あけましておめでとうございます🎍 今年もどうぞよろしくお願いします! さて、この記事では、IRIS ターミナルに(こっそり)追加された便利機能をご紹介します!(つい最近知りまして、びっくりしました) 2023/4/13 追記:Pythonシェルへ切り替えるメソッドのショートカットが追加されていたので返信欄に追記しました。 IRIS ターミナルで以前実行したコマンドを再実行する場合、上矢印キーを連打しながらコマンドを探されていると思うのですが、IRIS 2021.1 から履歴表示と、履歴番号を指定した実行ができるようになっていました! では早速、履歴(history)の使い方をご紹介します。これがあれば、もう、上矢印キーを連打せずに以前実行したコマンドを再実行できます!! まずは、履歴を作るため、いくつかコマンドを実行します。​​​ ユーザ名:_system パスワード:*** USER> USER>write $ZDATE($NOW(),16) 2022年1月6日 USER> USER>write $ZV IRIS for Windows (x86-64) 2021.1 (Build 215U) Wed Jun 9 2021 09:39:22 EDT USER> USER>write $system.Util.ManagerDirectory() c:\intersystems\irishealth\mgr\ USER> ここで、:? と入力してみます。 (なんと、オプションが表示されます!!) USER>:? :<number> Recall command # <number> :? Display help :alias Create/display aliases :clear Clear history buffer :history Display command history :unalias Remove aliases :history (または :h)を実行すると、履歴が表示されます! USER>:history 1: _system 2: write $ZDATE($NOW(),16) 3: write $ZV 4: write $system.Util.ManagerDirectory() 5: :? 6: :history コロン(:)と履歴番号を指定し、以前実行したコマンドを再実行してみます。(:4 と入力しています。) USER>:4 write $system.Util.ManagerDirectory() c:\intersystems\irishealth\mgr\ USER> 上矢印キーを連打せずに、過去のコマンドを実行できました!便利です 続いて、alias オプションを使うとコマンドのショートカットが作成できるようですので、それも試してみます。 以下の実行例では、TESTネームスペースに移動した後、IRIS ターミナルをSQL実行モードに変更し、SQLを実行しています。 USER>set $namespace="test" TEST>do $system.SQL.Shell() SQL Command Line Shell ---------------------------------------------------- The command prefix is currently set to: <<nothing>>. Enter <command>, 'q' to quit, '?' for help. [SQL]TEST>>select * from Training.Person 1. select * from Training.Person ID Email Name 1 yamada@majorcorp.com 山田たろう 1 Rows(s) Affected statement prepare time(s)/globals/cmds/disk: 0.0462s/3307/171368/2ms execute time(s)/globals/cmds/disk: 0.0002s/2/675/0ms cached query class: %sqlcq.TEST.cls166 --------------------------------------------------------------------------- [SQL]TEST>>quit TEST> なかなか覚えにくいコマンドに対して、alias を設定しておくと便利そうですので、ターミナルを SQL の実行環境に変更する do $system.SQL.Shell() を設定してみます。 設定方法は以下の通りです。 :alias 名称 コマンド $system.SQL.Shell() を sqlmode の名称で alias に設定する例は以下の通りです。 TEST>:alias sqlmode do $system.SQL.Shell() TEST>:alias sqlmode do $system.SQL.Shell() 早速、設定した alias を使ってみましょう! TEST>:sqlmode do $system.SQL.Shell() SQL Command Line Shell ---------------------------------------------------- The command prefix is currently set to: <<nothing>>. Enter <command>, 'q' to quit, '?' for help. [SQL]TEST>>quit TEST> 無事、実行できました! (alias 名は省略できるので、上記登録の場合 :s でも実行できるようでした。) メモ:2021.2プレビュー版では、do $system.SQL.Shell() が alias 名 sql で事前に登録されているため、:sql で SQL 実行モードに切り替えできました。 履歴(history)や alias の例については、ドキュメントにも記載がありますので、併せてご参照ください! 前のコマンドの繰り返し いつの間にか、:py も追加されていました。(Pythonシェルへ切り替わります。) USER>:py Python 3.9.5 (default, Jan 13 2023, 15:20:22) [MSC v.1927 64 bit (AMD64)] on win32 Type quit() or Ctrl-D to exit this shell. >>> import datetime >>> datetime.datetime.now() datetime.datetime(2023, 4, 13, 11, 16, 43, 487481) >>> もちろん、以下メソッドの実行でも切り替わります。 do ##class(%SYS.Python).Shell()
記事
Shintaro Kaminaka · 2020年9月4日

IRIS for Health 上でFHIR リポジトリ+OAuth2 認可サーバ/リソースサーバ構成を構築する パート1

開発者の皆さん、こんにちは。 今回の記事ではFHIRと組み合わせて使用されるケースが増えてきている、権限の認可(Authorization)を行うためのOAuth2について取り上げます。 まずこのパート1では、IRIS for HealthおよびApacheのDockerコンテナの起動と、IRIS for Health上で、OAuth2認可サーバ機能を構成し、REST開発ツールPostmanからアクセスし、アクセストークンを取得する方法について解説します。さらにパート2以降では、IRIS for HealthにFHIRリポジトリ機能を追加し、OAuth2リソースサーバ構成を追加して、Postmanからアクセストークンを使用したFHIRリクエストの実行方法まで解説します。 InterSystems製品のOAuth2機能の解説については、すでにいくつかの記事が開発者コミュニティ上に公開されていますが、今回は改めて最新バージョンでの構成方法を解説したいと思います。InterSystems IRIS Open Authorization Framework(OAuth 2.0)の実装 - パート1 今回の記事では、最新のInterSystems IRIS for Health 2020.3 Preview Editionを使用します。実際にこの記事を元にして、環境を構築してみようと思われた方は必ずこのバージョン以降のキットを使用してください。一部機能がこのバージョン以前の製品には含まれていません。 事前準備 まずは事前準備です。セキュアな環境を構築するために、色々と準備することが多いです。 IRIS for Health 2020.3 Preview EditionはDockerコンテナバージョンだけが提供されています。(InterSystems Docker Hub/IRIS for Health)また、OAuth2構成を行うためには、WebサーバおよびSSL構成を行う必要があります。今回はApacheを使用します。Apache上でSSL構成を行う場合、SSL構成の証明書は正しくサーバのホスト名と一致している必要があります。この点を注意してください。 intersystems-jp GitHub リポジトリからのサンプルファイルの取得 インターシステムズ開発者コミュニティ専用のGitHubリポジトリに今回の構成で使用するサンプルの docker-compose.yml/Dockerfile等が公開されています。まずは以下のコマンドでご利用の環境にこのファイルを展開してください。(この記事の添付ファイルにも追加されているのでそちらからでもOKです。)このdocker-compose.yml/Dockerfile等のファイルは、OpenExchangeに公開されているiris-webgateway-exampleアプリケーションを参考に作成しています。 git clone https://github.com/Intersystems-jp/IRIS4H-OAuth2-handson.git 使用するキットに合わせた構成の変更 このdocker-compose.ymlファイルでは、IRIS for Healthのコンテナと、docker buildコマンドでbuildされるApache(httpd)のコンテナの二つが起動するように構成されています。GitHubで配布しているdocker-compose.ymlファイルでは、IRIS for Health Community Edition Preview Edition(2020.3.200.0) を指定しています。Community Editionはインターシステムズ製品の評価のために利用していただくことができます。 iris: image: store/intersystems/irishealth-community:2020.3.0.200.0 異なるバージョン(正式リリースバージョンやより新しいバージョン)を使用する場合は、この部分の指定を変更してください。 Apacheの方のコンテナはDockerfileの内容でbuildされますが、その際にApacheからIRISに接続するためのWebGatewayのキットが必要になります。キットの入手方法についてはインターシステムズパートナーの方々はWRCのキットダウンロードサイトするか、またはWRCサポートセンターへお問い合わせください。それ以外の方々はお手数ですが、こちらのアドレスまでお問い合わせください。 入手した製品に合わせてDockerfileの以下の箇所を変更します。ホストマシンのOSがWindows/Ubuntu/CentOSいずれであっても、ベースとなるhttpdのコンテナOSがDebianであるため、platformはlnxubuntux64の指定となります。 ARG version=2020.3.0.200.0 ARG platform=lnxubuntux64 ADD WebGateway-${version}-${platform}.tar.gz /tmp/ SSL証明書の用意 次にSSL証明書を用意します。OAuth2 認可アクセス時には、そのWebサーバで設定されているSSL証明書がアクセスしているURLと一致しているか確認を行います。公式な証明書でなくても、openssl等を使用した証明書作成で問題はありません。証明書作成時にCommon Nameにホスト名を入力してください。 また、作成した証明書は起動時に自動で読み込むため、パスフレーズが不要なファイルに変更しておく必要があります。以下のコマンドを参考にしてください。 $ openssl rsa -in cert.key.org -out cert.key 作成された CRTファイルおよび、KEYファイルをそれぞれ server.crt / server.key というファイル名で、Dockerfileと同じディレクトリにおいてください。 また、Apache Webサーバで利用する以外にも、OAuth2の設定でSSL証明書が必要になります。これらはホスト名の入力等は必要がありませんが、3セット作成しておいてください。(以降の設定ではauth.cer/auth.key , client.cer/client.key , resserver.cer/resserver.key として登場します。 ) dockerビルド と dockerコンテナの起動 これでようやく準備完了です!今ディレクトリには、DLした4つのファイル以外に、Webゲートウェイのインストールキット、そして二つのSSL証明書がある状態です。各ファイルのアクセス・実行権限等にもご注意ください。(例えば私は、webgateway-entrypoint.shに実行許可を追加しました。) docker-compose build docker-compose up -d 起動したら、docker ps コマンドで二つのコンテナが起動していることを確認します。 ApacheのコンテナIMAGE名:<directoryname>_web IRIS for Healthのコンテナ:store/intersystems/irishealth-community:2020.3.0.200.0(あるいはそれぞれ指定したIMAGE) 次は、以下の3つの方法で管理ポータルにアクセスしてみてください。最後の3番目の方法でうまくアクセスできれば、Apache Webサーバ経由のSSL構成は成功です! http://<hostname>:52773/csp/sys/UtilHome.csp : このURLはIRIS コンテナのPrivate Apache経由のアクセスです。構成したApacheは経由しません。 http://<hostname>/csp/sys/UtilHome.csp : このURLは構成したApacheを経由して管理ポータルにアクセスしています。 https://<hostname>/csp/sys/UtilHome.csp : このURLは構成したApache経由でSSL接続を使用して管理ポータルにアクセスしています。 SSL構成の作成 それでは、IRIS for Healthが起動し、管理ポータルにアクセスできるようになったので、最後の準備としてSSL構成を作成しましょう。 管理ポータル→システム管理→セキュリティ→SSL/TLS構成 と進み、先ほど作成した3ペアの証明書キーを使って、SSLの構成を3つ作成しておいてください。 名前は自由に決めることができますが、この記事では過去のOAuth2関連記事にならって、SSL4AUTH/SSL4CLIENT/SSL4RESSERVER としています。 *ホストとコンテナのディレクトリ共有について docker-composeファイルに記載されている以下のvolumes 指定によって、ホストの現在のディレクトリ位置=コンテナ内の /ISC ディレクトリ となっています。上記の設定等で証明書ファイルを指定する場合は、このディレクトリを活用してください。 volumes: - .:/ISC このディレクトリには、ファイルだけでなくIRISのデータベースファイルや構成ファイルも配置されます。詳しくはドキュメント「永続インスタンス・データを保存するための永続的な %SYS」をご覧ください。 IRIS for HealthでOAuth2の構成 いよいよIRIS for HealthにOAuth2を使ってアクセスするための具体的な準備に入ります! OAuth2認可サーバ構成 まずはOAuth2認可サーバの構成です!管理ポータル→システム管理→セキュリティ→OAuth 2.0→サーバ と進みます。 以下の内容に従って設定します。 「一般」タブ設定内容 発行者エンドポイント:ホスト名 <実際のホスト名を入力します> :プレフィックス 任意の値を入力できますが、ここでは「authserver」としています。 サポートする許可タイプ この記事の中では認証コード(Authorization Code)しか使用しませんが、他の許可タイプ(Grant Type)もテストしてみたい方はチェックを追加してください。また、「JWT承認」にもチェックを追加します。 SSL/TLS構成 先ほど追加したSSL構成を指定します。 「スコープタブ」では、「サポートしているスコープを追加」をクリックして追加します。あとで、表示される認可コード(Authorization Code)のログイン画面ではここで記述した「説明」が表示されます。 「間隔」タブはデフォルトから変更する内容はありません。「JWT」タブでは署名アルゴリズムに「RS512」を選択してみましょう。 最後の「カスタマイズ」タブでは、トークン・クラスを生成 の指定を %OAuth2.Server.JWT に変更します。 入力したら、「保存」ボタンを押して、構成を保存します。 これで、IRIS for HealthがOAuth2認可サーバとして稼働する基本の設定ができました。早速Postmanからアクセスしてアクセストークンが取得できるか試してみましょう! しかし、その前にあと2つ構成を行わなければいけません。 クライアントデスクリプションを追加する まずはOAuth2クライアントとしてアクセスするPOSTMANの情報を追加します。OAuth2クライアント登録は動的登録などで追加されることもあります。 サーバ構成画面の「クライアントデスクリプション」をクリックして先に進みます。 「クライアントデスクリプションを作成」をクリックしてエントリを追加します。 以下の内容に従ってクライアントデスクリプションを作成します。 「一般」タブ設定内容 名前 任意の名前を入力します。ここでは postmanとしました。 クライアントの種別 「機密」を選択します。 リダイレクトURL 「URLを追加」ボタンから追加します。postmanのリダイレクトURLとしてhttps://www.getpostman.com/oauth2/callbackを指定します。 サポートする許可タイプ OAuth2認可サーバの設定で構成した内容と同じ「認証コード」(Authorization Code) を指定します。(デフォルト)他の許可タイプもテストしてみたい場合はチェックを追加します。ただし、認可サーバの構成と同じ設定にする必要があります。また、「JWT承認」にもチェックを入れます。ただし、ここで指定する 認証署名アルゴリズム サポートする許可タイプで「JWT承認」をチェックすると、選択できるようになります。「RS512」を選択します。 入力できたら「保存」ボタンを押してクライアントデスクリプションを保存します。 「クライアント認証情報」タブをクリックすると、このエントリに対するクライアントIDとクライアントの秘密鍵を確認することができます。POSTMANからテストするときはこのIDと秘密鍵が必要になります。 ウェブアプリケーションの追加 POSTMANからアクセスする前にもう一つ大事な設定を加える必要があります。OAuth2認可サーバ構成画面で、この構成のエンドポイントが https://<hostname>/authserver/oauth2 と決定されました。このエンドポイントへのアクセスが正しくIRISで処理されるために、このURLパスに対するウェブアプリケーションの追加を行う必要があります。 システム管理→セキュリティ→アプリケーション→ウェブ・アプリケーション と進み、「新しいウェブ・アプリケーションを作成」をクリックします。 OAuth2のウェブ・アプリケーションのテンプレートが用意されているので、まず「コピー元」から「/oauth2」を選択します。 「ウェブ・アプリケーションの編集」設定項目 コピー元 /oauth2 プルダウンから必ずこちらを先に選択します。 名前 /authserver/oauth2 有効 「REST」のラジオボタンをチェックします。 各値を入力したら保存します。 POSTMANからOAuth2のテストを行う それではPOSTMANからテストしてみましょう。テストの実行は他のツールや実際のプログラムから行うこともできます。POSTMANの詳しい説明はこの記事では触れませんが、一点注意点として、POSTMANのSettingでSSL certificate verificationはOFFに変更するようにしてください。 POSTMANで新しいリクエストを作成後、AuthorizationタブのTYPEで「OAuth 2.0」を選択し、「Get New Access Token」をクリックします。 次の画面で、以下の内容に従って値を入力していきます。 「GET NEW ACCESS TOKEN」設定項目 Token Name 任意の名前を入力します。 Grant Type 「Authorization Code」を指定します。 Callback URL https://www.getpostman.com/oauth2/callback Auth URL https://<hostname>/authserver/oauth2/authorize?ui_locales=jaエンドポイント+/authorize の値を入力します。ui_locales=ja を追加することで日本語のログイン画面を表示させることができます。 Auth Token URL https://<hostname>/authserver/oauth2/tokenエンドポイント+/token の値を入力します。 Client ID クライアントデスクリプションの登録後にクライアント認証情報タブに表示される クライアントID を入力します。 Client Secret クライアントデスクリプションの登録後にクライアント認証情報タブに表示される クライアントの秘密鍵 を入力します。 Scope 認可サーバ構成で登録したスコープを入力します。 scope1 など。スペースで区切って複数指定することもできます。 State CSRF対策などで使用されるStateパラメータを入力します。特に使用しませんが空白にできないので、任意の文字列を入力しています。 パラメータ入力後、「Request Token」ボタンを押すと、以下のようなログイン画面が表示されたでしょうか? 管理ポータルにアクセスしているユーザ情報 (_SYSTEM等) でログインしてみてください。 ログイン後の次の画面では、このアプリケーションに権限の許可を与えるかどうか決定できます。「許可」をクリックしたあと、次の画面で以下のようにAccess Tokenが表示されれば、アクセストークン取得テストは成功です! OpenID Connectのテスト IRIS for Healthでは、OAuth2の認可処理だけでなく、OpenID Connectに準拠した認証処理を実施することができます。詳細はこちらのドキュメントを参照してください。 今回の構成では実はOpenID Connectの設定も有効になっています。OpenID ConnectののIDトークンも取得できるかテストしてみましょう! やり方は簡単です。先ほどのGET NEW ACCESS TOKEN画面で、Scopeに「openid」を追加してリクエストしてみましょう。 権限の要求ページでも、OpenID Connectが表記されます。ログイン処理を行い、許可を与えた後に次の画面が表示されたらIDトークン(id_token)も取得できることを確認してください。(画面を下にスクロールする必要があります。) いかがでしたか?Access Token そして id_tokenが取得できたでしょうか? 証明書等、少々手間がかかる準備もありますが、データベースプラットフォームであるIRIS for Health上でもこれだけ簡単にOAuth2認可サーバを構築することができました。 この連載の次のパートでは、いよいよFHIRリポジトリを構築し、FHIRリポジトリのOAuth2リソースサーバ登録、そして再びPOSTMANからOAuth2アクセストークンを使用したFHIRリポジトリへRESTアクセスする方法を紹介していきます。 記事を参考にしてアクセストークンの取得まで試してみたところ問題なく動作しました。 有益な記事をアップして頂きありがとうございます。 以下、記載されている手順以外で実行したものを列挙させて頂きます。 他に試す方のご参考になれば幸いです。 **SSL証明書の用意** Apache Webサーバー用のSSL証明書を作成 ``` openssl genrsa 2048 > server.key openssl req -new -key server.key > server.csr → CommonNameにDockerホストのホスト名を指定 openssl x509 -days 100 -req -signkey server.key < server.csr > server.crt ``` OAuth2.0用のSSL証明書を作成 ``` openssl genrsa 2048 > auth.key openssl x509 -days 100 -req -key auth.key -out auth.cer ``` **dockerビルド と dockerコンテナの起動** Dockerfileの38行目に以下を追加し、権限を設定 ``` RUN chmod +x /opt/webgateway/bin/webgateway-entrypoint.sh ``` **POSTMANからOAuth2のテストを行う** 自己署名証明書のためPostmanで「self signed certificate」エラーが発生するため、 設定から「SSL certificate verification」をOFFに設定。