【IRIS/Cache】クラスを隠蔽する

クラスには、秘匿しておきたい技術やコメントがてんこ盛りです。
このクラスを社外の環境に配置して、社外のそれこそ同業他社の目に触れる状態で置いておくのは技術の漏洩に繋がる可能性が高いです。

そこでクラスの隠蔽を行います。

今回は、社外にクラスを配置するのはチョット…って時に活用する、クラスの隠蔽方法について解説します。

はじめに

社外環境におけるクラス配置って、どうされていますか?
リリースして、そのままにしておく事が多いのではないでしょうか。

愚痴混じりのコメントで社外の方に見られると気まずいソース、ひた隠しにしたいソース等々、そのまま放置するには憚られるクラスが存在していると、気が気で眠れないですよね。

そんな時は、クラスを隠蔽するに限ります。
バレないように隠しちゃいましょう。

隠蔽コマンド

クラスの隠蔽コマンドは下記になります。
ターミナルから対象のネームスペースに移動し、実行してください。

d $system.OBJ.MakeClassDeployed(クラス名, qspec, fulldeploy)

引数

引数は3つあります。

引数初期値説明
クラス名null・単一指定、カンマによるリスト、添え字付き配列での指定が可能
・「*」or「?」を利用したワイルドカードが使用可能
・対象外にする場合、項目の前に「’」を付与する

※大体いつも通りの指定方法
qspecnull下記コマンドにてフラグや修飾子が確認可能
d $system.OBJ.ShowQualifiers()
d $system.OBJ.ShowFlags()
fulldeploy01を渡すことで、実行可能な最小限の形に隠蔽します

動作確認

クラス隠蔽後の状態と動作を確認するため、下記サンプルを用意しました。
インデックス・パラメータ・プロパティ・静的/動的関数等々を揃えました。

Class developer.deploy.SampleData Extends %Persistent
{

Parameter NAME = "デプロイ用です";

Index uniq On (test1, test2) [ PrimaryKey ];

/// プロパティコメント
Property test1 As %String(CAPTION = "test1");

Property test2 As %String(CAPTION = "test2");

Property num1 As %Integer(CAPTION = "何らかの数値");

/*
関数コメント
*/
ClassMethod GetSampleText(text As %String) As %String
{
	q "びっくり仰天:"_text
}

/// 関数コメント
Method GetAddNum() As %Integer
{
	// めっちゃ恥ずかしいコメント!
	q num1 * 100
}

Query GetTest1(text1 As %String, text2 As %String) As %SQLQuery
{
	select num1 from developer_deploy.SampleData where test1=:text1 & test2=:test2
}

Trigger SampleTrigger [ Event = INSERT, Time = AFTER ]
{
	s test1 = {test1*N}
	, test2 = {test2*N}
	, num1  = {num1*N}
	
	s ^developer.deploy.SampleDataI("uniq", " "_test1, " "_test2)=$lb("",num1)
}

XData SampleXData
{
<title>
<text>ここら辺にも恥ずかしいコメントが!</text>
</title>
}

Storage Default
{
<Data name="SampleDataDefaultData">
<Value name="1">
<Value>%%CLASSNAME</Value>
</Value>
<Value name="2">
<Value>test1</Value>
</Value>
<Value name="3">
<Value>test2</Value>
</Value>
<Value name="4">
<Value>num1</Value>
</Value>
</Data>
<DataLocation>^developer.deploy.SampleDataD</DataLocation>
<DefaultData>SampleDataDefaultData</DefaultData>
<IdLocation>^developer.deploy.SampleDataD</IdLocation>
<IndexLocation>^developer.deploy.SampleDataI</IndexLocation>
<StreamLocation>^developer.deploy.SampleDataS</StreamLocation>
<Type>%Storage.Persistent</Type>
}

}

クラス隠蔽を行う前に、作成したクラスをエクスポートしておいて下さい

では、実際にクラスの隠蔽を行ってみましょう。
ターミナルで、下記コマンドを実行します。

※ネームスペース「sample」で実行する予定です。

zn "sample"
d $system.OBJ.MakeClassDeployed("developer.deploy.SampleData")

下記は、隠蔽後のクラスの状態になります。

ClassMethod, Method, Triggerや「/**/コメント」が対象となり、関数の処理やコメントが隠蔽され参照できなくなっています。
また、Query, XData, 「/// コメント」に関しては、全く影響がないことが分かります。

Class developer.deploy.SampleData Extends %Persistent
{

Parameter NAME = "デプロイ用です";

Index uniq On (test1, test2) [ PrimaryKey ];

/// プロパティコメント
Property test1 As %String(CAPTION = "test1");

Property test2 As %String(CAPTION = "test2");

Property num1 As %Integer(CAPTION = "何らかの数値");

ClassMethod GetSampleText(text As %String) As %String
{
}

/// 関数コメント
Method GetAddNum() As %Integer
{
}

Query GetTest1(text1 As %String, text2 As %String) As %SQLQuery
{
	select num1 from developer_deploy.SampleData where test1=:text1 & test2=:test2
}

Trigger SampleTrigger [ Event = INSERT, Time = AFTER ]
{
}

XData SampleXData
{
<title>
<text>ここら辺にも恥ずかしいコメントが!</text>
</title>
}

Storage Default
{
~~ Storage情報 略 ~~
}

}

表示が出ていなくても関数の機能が死んだ訳ではありません。
関数を実行し、正常に戻り値が返ってきている事が確認できます。

クラス隠蔽後は、エクスポートができなくなります。
これでセキュリティーも万全ですね。

デプロイ状態から元に戻す

クラスの隠蔽は不可逆変化になるため、一度実行すると元に戻すことができません。
 ※ホイホイ簡単に戻られても困りますよね。

とは言え、エラー発生時のデバッグ等、ここぞという時にクラスが参照できないと解決できないケースはあります。

その時は、バックアップしていたクラスを再度インポートしましょう。
クラスのインポート後は元の状態に戻り、クラスの状態が確認可能になります。

諸々作業が終われば、再度デプロイを実行しましょう。

fulldeploy

第三引数に1を渡すと、クラスを開けないレベルで隠蔽します。
その名の通り、完全なる隠ぺいです。

永続クラス(%Persistent)・シリアルクラス(%SerialObject)等は非対称です。

簡単なサンプルを用意して「fulldeploy」の効果を確認してみます。

Class developer.deploy.FullDeployed Extends %RegisteredObject
{
ClassMethod Sample() As %String
{
	q "fullデプロイ"
}
}

第三引数のfulldeploy=1を渡して、隠蔽コマンドを実行します。

d $system.OBJ.MakeClassDeployed("developer.deploy.FullDeployed",,1)

コマンド実行後、スタジオ等でクラスを開こうとすると、下記エラーが表示され開くことができなくなります。


エラー #5360: クラス ‘developer.deploy.FullDeployed’ はスタブ名です。開くことはできません

完全に隠蔽されました。
もう、クラス内部に記述している関数名すら分からないレベルです。

念のため、動作確認としてターミナルより関数の実行を行います。

ターミナル実行結果

このような状態でも、内部のクラスの機能が実行可能です。
これでクラスの構造ごと、秘密が守れます。

おわりに

以上で、クラスの隠蔽方法の解説を終わります。

クラス情報は、秘密の宝庫なので極力隠蔽しておきたいですよね。

また、完全隠蔽を行うのであれば、データクラスと処理を行うクラスは分けておいた方が良さそうです。
データクラスにまで処理を記述してしまうと、その関数は完全隠蔽対象外となります。

クラスの完全隠蔽を視野に入れるのであれば、クラス構成を見直す必要があるかもしれませんね。

以上、皆様の秘密が守られることを祈っております。