REST データ・サービスのプロパティー・ファイル

REST データ・サービスを構成するには、REST のプロパティー・ファイルを編集して、データ・グリッドで必要なエンティティー・スキーマを定義します。

REST データ・サービスのプロパティー・ファイルは、eXtreme Scale REST データ・サービスのメイン構成ファイルです。このファイルは、キーと値のペアが含まれた Java プロパティー・ファイルです。デフォルトでは、REST データ・サービス・ランタイムで、クラスパス内の適切な名前の wxsRestService.properties ファイルが検索されます。このファイルは、wxs.restservice.props システム・プロパティーを使用して、明示的に定義することもできます。

-Dwxs.restservice.props=/usr/configs/dataservice.properties

REST データ・サービスがロードされるときに、 使用されるプロパティー・ファイルがログ・ファイルに以下のように表示されます。

CWOBJ4004I: The eXtreme Scale REST data service properties files were loaded: [/usr/configs/RestService.properties]

REST データ・サービスのプロパティー・ファイルでは、以下のプロパティーがサポートされます。

表 1. REST データ・サービスのプロパティー
プロパティー 説明
catalogServiceEndPoints <host:port> というフォーマットの、カタログ・サービス・ドメインのホストとポートの必須コンマ区切りリスト。WebSphere® eXtreme Scale と統合された WebSphere Application Server を使用して REST データ・サービスをホストする場合には、これはオプションです。詳しくは、スタンドアロン・カタログ・サービスの開始を参照してください。

catalogServiceEndPoints=

server1:2809,server2:2809

objectGridNames REST サービスに公開するデータ・グリッドの必須名。少なくとも 1 つの ObjectGrid 名が必要です。 複数の ObjectGrid 名は、以下のように、コンマを使用して区切ります。

ECommerceGrid,InventoryGrid

objectGridClientXML ObjectGrid クライアント・オーバーライド XML ファイルのオプションの名前。 ここで指定した名前のファイルが、クラスパスからロードされます。 デフォルトは、以下のとおりです。

/META-INF/objectGridClient.xml.

ogClientPropertyFile ObjectGrid クライアント・プロパティー・ファイルのオプションの名前。このファイルには、ObjectGrid クライアント・セキュリティーを使用可能にするために必要なセキュリティー・プロパティーが含まれています。このプロパティー・ファイル内で「securityEnabled」属性が設定されていると、REST サービスが使用する ObjectGrid クライアントでセキュリティーが使用可能になります。また、このプロパティー・ファイル内で、「credentialGeneratorProps」を「user:pass」形式の値か、もしくは {xor_encoded user:pass} の値に設定する必要があります。
loginType ObjectGrid クライアント・セキュリティーが使用可能であるとき、REST サービスが使用する認証のタイプ。ObjectGrid クライアント・セキュリティーが使用可能でないときは、このプロパティーは無視されます。
ObjectGrid クライアント・セキュリティーが使用可能で、loginType が basic に設定されている場合、REST サービスは以下を実行します。
  • ObjectGrid クライアント・プロパティー・ファイルの「credentialGeneratorProps」プロパティーに指定された資格情報を使用して、サービス初期化時の ObjectGrid 操作を行う。
  • HTTP 基本認証を使用して、要求ごとの ObjectGrid セッション操作を行う。
ObjectGrid クライアント・セキュリティーが使用可能で、loginType が none に設定されている場合、REST サービスは以下を実行します。
  • ObjectGrid クライアント・プロパティー・ファイルの「credentialGeneratorProps」プロパティーに指定された資格情報を使用して、サービス初期化時の ObjectGrid 操作を行う。
  • ObjectGrid クライアント・プロパティー・ファイルの「credentialGeneratorProps」プロパティーに指定された資格情報を使用して、要求ごとの ObjectGrid セッション操作を行う。
traceFile トレース出力のリダイレクト先ファイルのオプションの名前。 デフォルトは、logs/trace.log です。
traceSpec eXtreme Scale ランタイム・サーバーが最初に使用するオプションのトレース仕様。デフォルトは、*=all=disabled です。 REST データ・サービス全体をトレースするには、 ObjectGridRest*=all=enabled を使用します。
verboseOutput true に設定すると、REST データ・サービス・クライアントは、障害発生時に追加診断情報を受け取ります。 デフォルトは false です。機密情報が明らかになる可能性があるため、実稼働環境では、このオプションの値は false に設定する必要があります。
maxResultsPerCollection 1 つの照会で返される結果の、任意指定の最大件数。デフォルト値は unlimited です。 有効な値は、任意の正整数です。
wxsRestAccessRightsFile サービス・オペレーションと ObjectGrid エンティティーのアクセス権を指定する、eXtreme Scale REST サービス・アクセス権プロパティー・ファイルの、任意指定の名前。このプロパティーが指定されると、REST サービスは、指定されたパスから、もしくはクラスパスから、ファイルのロードを試行します。

WebSphere eXtreme Scale 構成

eXtreme Scale REST データ・サービスは、EntityManager API を使用して eXtreme Scale と対話します。eXtreme Scale データ・グリッドにエンティティー・スキーマが定義され、そのエンティティーのメタデータが REST データ・サービスによって自動的に消費されます。エンティティー・スキーマの構成について詳しくは、エンティティー・スキーマの定義を参照してください。

例えば、以下のように、eXtreme Scale データ・グリッドで Person を表すエンティティーを定義できます。
@Entity															
public class Person {
		@Id String taxId;
		String firstName;
		String lastName;
}
ヒント: ここで使用されているアノテーションは、com.ibm.websphere.projector.annotations パッケージ内にあります。

REST サービスは、データ・サービス (EDMX) 文書用の ADO.NET エンティティー・データ・モデルを自動的に作成します。この文書は、$metadata URI を使用して利用できます。

http://localhost:8080/wxsrestservice/restservice/NorthwindGrid/$metadata

データ・グリッドを構成して実行中にした後に、eXtreme Scale クライアントを構成してパッケージします。eXtreme Scale REST データ・サービス・クライアント・パッケージの構成の詳細については、REST データ・サービスのインストール にあるパッケージ化およびデプロイメントの情報を参照してください。

エンティティー・モデル

WebSphere eXtreme Scale エンティティーは、エンティティー・アノテーションまたはエンティティー・メタデータ記述子ファイルを使用してモデル化されます。エンティティー・スキーマの構成方法について詳しくは、エンティティー・スキーマの定義を参照してください。eXtreme Scale REST サービスはエンティティー・メタデータを使用して、データ・サービスの EDMX モデルを自動的に作成します。

このバージョンの WebSphere eXtreme Scale REST データ・サービスには、以下のスキーマの制限があります。
  • 区画化されたデータ・グリッド内のエンティティーを定義する際に、 すべてのエンティティーは、ルート・エンティティーへの直接または間接の単一値アソシエーション (キー・アソシエーション) を持つ必要があります。 WCF データ・サービス・クライアント・ランタイムは、正規アドレスを使用して直接すべてのエンティティーにアクセスできる必要があります。 そのため、区画ルーティングで使用されるルート・エンティティー (スキーマ・ルート) のキーは、子エンティティーのキーの一部である必要があります。

    以下に例を示します。

    @Entity(schemaRoot=true)
    public class Person {
        @Id String taxId;
        String firstName;
        String lastName;
        @OneToMany(mappedBy="person") 
        List<Address> addresses;
    
    }
    
    @Entity
    public class Address {
        @Id int addrId;
        @Id @ManyToOne Person person;
        String street;
    }
  • 双方向および単一方向のアソシエーションがサポートされます。 ただし、単一方向アソシエーションは単一方向にのみナビゲートでき、Microsoft 仕様ではすべてのアソシエーションが双方向である必要があるため、 Microsoft WCF Data Services クライアントからの単一方向アソシエーションは必ずしも機能するわけではありません。
  • 参照制約はサポートされません。 WebSphere eXtreme Scale ランタイムは、エンティティー間のキーを検証しません。エンティティー間のアソシエーションは、クライアントで管理する必要があります。
  • 複合型はサポートされません。 EntityManager API は、組み込み可能属性をサポートしません。すべての属性は、単純型属性である必要があります (下にリストされた単純属性型を参照)。 非単純型属性は、クライアントの観点から、バイナリー・オブジェクトとして扱われます。
  • エンティティー継承はサポートされません。 EntityManager API は継承をサポートしません。
  • メディア・リソースおよびメディア・リンクはサポートされません。 データ・サービスの Conceptual Schema Definition Language Document 内の EntityType の HasStream 属性は使用されません。

EDM データ型と Java データ型間のマッピング

OData プロトコルは、抽象型システムで、以下のリストの Entity Data Model (EDM) 型を定義します。 以下のトピックで、エンティティーで定義された基本型に基づいて eXtreme Scale REST アダプターが EDM 型を選択する方法について説明します。EDM 型の詳細については、MSDN Library: Abstract Type System を参照してください。

WCF Data Services では、以下の EDM 型が使用できます。

  • Edm.Binary
  • Edm.Boolean
  • Edm.Byte
  • Edm.DateTime
  • Edm.Time
  • Edm.Decimal
  • Edm.Double
  • Edm.Single
  • Edm.Float
  • Edm.Guid *
  • Edm.Int16
  • Edm.Int32
  • Edm.Int64
  • Edm.SByte
  • Edm.String

EDM 型 Edm.Guid は、eXtreme Scale REST データ・サービスではサポートされません。

EDM 型への Java 型のマッピング

eXtreme Scale REST データ・サービスは、基本エンティティー型を EDM 型に自動的に変換します。$metadata URI を使用して Entity Data Model Extensions (EDMX) メタデータ文書を表示することで、型マッピングを表示できます。 EDM 型は、クライアントがデータを読み取り、REST データ・サービスに書き込むために使用されます。
表 2. EDM 型へマッピングされた Java 型. エンティティーで定義された Java 型が EDM データ型にマッピングされる様子が表に示されます。照会を使用してデータを取得する際に、データはこれらの型で表されます。
Java 型 EDM 型
boolean java.lang.Boolean Edm.Boolean
byte java.lang.Byte Edm.SByte
short java.lang.Short Edm.Int16
int java.lang.Integer Edm.Int32
long java.lang.Long Edm.Int64
float java.lang.Float Edm.Single
double java.lang.Double Edm.Double
java.math.BigDecimal Edm.Decimal
java.math.BigInteger java.math.BigInteger
java.lang.String Edm.String
char char
java.lang.Character java.lang.Character
Char[] Char[]
java.lang.Character[] java.lang.Character[]
java.util.Calendar Edm.DateTime
java.util.Date java.util.Date
java.sql.Date java.sql.Date
java.sql.Timestamp java.sql.Timestamp
java.sql.Time java.sql.Time
その他の型 Edm.Binary

Java 型への EDM 型のマッピング

更新要求および挿入要求の場合、更新または eXtreme Scale REST データ・サービスに挿入されるデータがペイロードで指定されます。サービスは、互換性のあるデータ型を、EDMX 文書で定義されたデータ型に自動的に変換できます。 REST データ・サービスは、以下の 2 つのステップから成るプロセスを使用して、値の XML エンコード・ストリング表現を正しい型に変換します。

  1. EDM 型が Java 型と互換性があることを確認するために、型検査が実行されます。 EDM 型によってサポートされるデータが Java によってサポートされるデータのサブセットである場合に、 EDM 型は Java 型と互換性があります。 例えば、Edm.int32 型は Java long 型と互換性がありますが、 Edm.int32 型は Java short 型と互換性がありません。
  2. ペイロードでストリング値を表すターゲットの Java 型オブジェクトが作成されます。
表 3. Java 型と互換性がある EDM 型
EDM 型 Java 型
Edm.Boolean ブール

java.lang.Boolean

Edm.SByte バイト

java.lang.Byte

short

java.lang.Short

int

java.lang.Integer

long

java.lang.Long

float

java.lang.Float

double

java.lang.Double

java.math.BigDecimal

java.math.BigInteger

char

java.lang.Character

Edm.Byte, Edm.Int16 short

java.lang.Short

int

java.lang.Integer

long

java.lang.Long

float

java.lang.Float

double

java.lang.Double

java.math.BigDecimal

java.math.BigInteger

char

java.lang.Character

Edm.Int32 int

java.lang.Integer

long

java.lang.Long

float

java.lang.Float

double

java.lang.Double

java.math.BigDecimal

java.math.BigInteger

Edm.Int64 long

java.lang.Long

double

java.lang.Double

java.math.BigDecimal

java.math.BigInteger

Edm.Double double

java.lang.Double

java.math.BigDecimal

Edm.Decimal double

java.lang.Double

java.math.BigDecimal

java.math.BigInteger

Edm.Single float

java.lang.Float

double

java.lang.Double

java.math.BigDecimal

Edm.String java.lang.String

char

java.lang.Character

Char[]

java.lang.Character[]

java.math.BigDecimal

java.math.BigInteger

Edm.DateTime java.util.Calendar

java.util.Date

java.sql.Date

java.sql.Time

java.sql.Timestamp

Edm.Time java.sql.Time

java.sql.Timestamp

時間型のマッピング

Java には、 日付、時間、またはその両方を格納するための 5 つの時間型があります (java.util.Date、java.sql.Date、java.sql.Time、java.sql.Timestamp、および java.util.Calendar)。 これらの型はすべて、エンティティー・データ・モデルでは Edm.DateTime として表されます。 eXtreme Scale REST データ・サービスは、Java 型に応じて、データを自動的に変換および正規化します。このトピックでは、開発者が時間型を使用する際に注意する必要があるいくつかの問題について説明します。

時間帯の差異

WCF Data Services では、Edm.DateTime 型での時間値の記述は常に協定世界時 (UTC) 標準を使用して表されます。 協定世界時 (UTC) は、グリニッジ標準時 (GMT) の国際的に認識される名前です。 協定世界時は、経度 0 度 (UTC 起点) で測定される時間です。 夏時間調整は UTC には適用されません。

エンティティー型と EDM 型の変換

クライアントが要求を REST データ・サービスに送信する際には、日時は以下の例のように GMT 時間帯の時間として表されます。

"2000-02-29T21:30:30.654123456"

REST データ・サービスは、 適切な Java 時間型インスタンスを構成してそのインスタンスをデータ・グリッドのエンティティーに挿入します。

eXtreme Scale REST データ・サービスに対して Java 時間型であるプロパティーをクライアントが要求した場合には、値は常に GMT 時間帯の値に正規化されます。例えば、エンティティー java.util.Date は以下のように構成されます。

Calendar c = Calendar.getInstance();
c.clear();									
c.set(2000, 1, 29, 21, 30, 30);
Date d = c.getTime();

Calendar.getInstance() ではローカル時間帯を使用して Calendar オブジェクトが作成されるため、 日時は Java プロセスのデフォルトの時間帯を使用して表されます。 ローカル時間帯が CST である場合、REST データ・サービスから取得される際に日付は、その時間の GMT 表現 ("2000-03-01T03:30:30") になります。

java.sql.Date の正規化

eXtreme Scale エンティティーは、Java type java.sql.Date で属性を定義できます。このデータ型には時間は含まれず、REST データ・サービスによって正規化されます。 つまり、eXtreme Scale ランタイムは、java.sql.Date 属性に時、分、秒、ミリ秒の情報を格納しません。時間帯オフセットに関係なく、日付は常にローカルの日付で表されます。

例えば、クライアントが値「2009-01-01T03:00:00」で java.sql.Date プロパティーを更新した場合、 CST 時間帯 (-06:00) の REST データ・サービスは、時間をローカル CST 時間の「2009-01-01T00:00:00」に設定した java.sql.Date インスタンスを単に作成します。 java.sql.Date 値を作成するために時間帯の変換は行われません。 REST サービス・クライアントがこの属性の値を取得したときに、「2009-01-01T00:00:00Z」と表示されます。 時間帯の変換が行われていたならば、値の日付は「2008-12-31」と表示され、正しくなくなります。

java.sql.Time の正規化

java.sql.Date と同様に、java.sql.Time 値は正規化され、日付情報が含まれなくなります。 つまり、eXtreme Scale ランタイムは、年、月、日を格納しません。時間はエポック時間 (1970 年 1 月 1 日) からの GMT 時間を使用して格納されます。これは java.sql.Time 実装と整合しています。

例えば、クライアントが値「2009-01-01T03:00:00」で java.sql.Time プロパティーを更新した場合、 REST データ・サービスは、ミリ秒を 3*60*60*1000 (3 時間) に設定して、java.sql.Time インスタンスを作成します。 REST サービス・クライアントが値を取得したときに、「1970-01-01:03:00:00Z」と表示されます。

アソシエーション

アソシエーションは、2 つの同位エンティティー間のリレーションシップを定義します。 eXtreme Scale REST サービスは、eXtreme Scale でアノテーションが付けられたエンティティーで定義されたエンティティーまたはエンティティー記述子 XML ファイルで定義されたエンティティーを使用してモデル化されたアソシエーションを反映します。

アソシエーションの保守

eXtreme Scale REST データ・サービスは、参照保全性制約をサポートしません。エンティティーが削除または追加されたときに参照が更新されるように、クライアントで保証する必要があります。 アソシエーションのターゲット・エンティティーがデータ・グリッドから削除されたのにもかかわらず、 ソース・エンティティーとターゲット・エンティティーとのリンクが削除されないと、リンク切れになります。 eXtreme Scale REST データ・サービスおよび EntityManager API ではリンク切れが許容され、CWPRJ1022W 警告としてリンク切れがログに記録されます。壊れたアソシエーションは、要求ペイロードから削除されます。

バッチ要求を使用して、アソシエーションの更新を単一のトランザクションでグループ化することで、リンク切れを回避できます。 バッチ要求の詳細については、次のセクションを参照してください。

ADO.NET Entity Data Model ReferentialConstraint エレメントは、eXtreme Scale REST データ・サービスでは使用されません。

アソシエーションの多重度

エンティティーには、多値アソシエーションまたは単一値アソシエーションを含めることができます。 多値アソシエーション (コレクション) は、1 対多または多対多のアソシエーションです。 単一値アソシエーションは、1 対 1 または多対 1 のアソシエーションです。

区画化されたデータ・グリッドでは、すべてのエンティティーに、ルート・エンティティーへの単一値キー・アソシエーションが含まれている必要があります。 このトピックのもう 1 つのセクションでは、キー・アソシエーションを定義する方法を説明します。ルート・エンティティーを使用してエンティティーを区画化するため、区画化されたデータ・グリッドでは、多対多アソシエーションは使用できません。 区画化されたデータ・グリッドの関係エンティティー・スキーマをモデル化する方法の例については、eXtreme Scale のスケーラブル・データ・モデルを参照してください。

以下の例で、アノテーションが付けられた Java クラスを使用してモデル化された EntityManager API アソシエーション型が どのように ADO.NET エンティティー・データ・モデルにマップされるのかを示します。

@Entity
public class Customer {
    @Id String customerId;
    @OneToOne TaxInfo taxInfo;
    @ManyToOne Address homeAddress;
    @OneToMany Collection<Order> orders;
    @ManyToMany Collection<SalesPerson> salespersons;
}

<Association Name="Customer_TaxInfo">
    <End Type="Model1.Customer" Role="Customer" Multiplicity="1" />
    <End Type="Model1.TaxInfo " Role="TaxInfo" Multiplicity="1" />
</Association>
<Association Name="Customer_Address">
    <End Type="Model1.Customer" Role="Customer" Multiplicity="1" />
    <End Type="Model1.Address" Role="TaxInfo" Multiplicity="*" />
</Association>
<Association Name="Customer_Order">
    <End Type="Model1.Customer" Role="Customer" Multiplicity="*" />
    <End Type="Model1.Order" Role="TaxInfo" Multiplicity="1" />
</Association>
<Association Name="Customer_SalesPerson">
    <End Type="Model1.Customer" Role="Customer" Multiplicity="*" />
    <End Type="Model1.SalesPerson" Role="TaxInfo" Multiplicity="*" />
</Association>

双方向アソシエーションおよび単一方向アソシエーション

エンティティー・アソシエーションは、単一方向または双方向にすることができます。 @OneToOne、@OneToMany、または @ManyToMany アノテーションで「mappedBy」属性を指定することで、 または 1 対 1、1 対多、または多対多の XML 属性タグで「mapped-by」属性を指定することで、 エンティティーは双方向になります。 OData プロトコルでは現在、すべてのエンティティーは双方向である必要があります。 これにより、クライアントは、両方向にナビゲーション・パスを生成できます。 eXtreme Scale EntityManager API では、単一方向アソシエーションをモデル化できます。これにより、メモリーの節約とアソシエーションの保守の簡素化が実現します。単一方向アソシエーションを使用する場合は、 REST データ・サービス・クライアントは、必ず定義されたアソシエーションを使用してアソシエーションをナビゲートする必要があります。

例えば、Address と Country の間に多対 1 の単一方向アソシエーションを定義した場合には、以下の URI は許可されません。

/restservice/CustomerGrid/Country('USA')/addresses

キー・アソシエーション

単一値アソシエーション (1 対 1 および多対 1) は、エンティティー・キーのすべてまたは一部として組み込むこともできます。 これは、キー・アソシエーションと呼ばれます。

キー・アソシエーションは、区画化されたデータ・グリッドを使用する際に必要になります。 区画化されたエンティティー・スキーマ内のすべての子エンティティーで、キー・アソシエーションを定義する必要があります。 OData プロトコルでは、すべてのエンティティーが直接アドレス可能である必要があります。 つまり、子エンティティーのキーに、区画化で使用するキーを含める必要があります。

以下の例では、Customer は、Order に対する 1 対多のアソシエーションを持っています。 Customer エンティティーはルート・エンティティーであり、customerId 属性を使用してエンティティーを区画化しています。 Order には、ID の一部として Customer が組み込まれています。

@Entity(schemaRoot="true")
public class Customer {
    @Id String customerId;
    @OneToMany(mappedBy="customer") Order orders
}

@Entity
public class Order {
    @Id int orderId;
    @Id @ManyToOne Customer customer;
    java.util.Date orderDate;
}

REST データ・サービスがこのモデルの EDMX 文書を生成する際に、 Customer キー・フィールドが、Order エンティティーの一部として自動的に組み込まれます。

<EntityType Name="Order">
<Key>
    <PropertyRef Name="orderId"/>
    <PropertyRef Name="customer_customerId"/>
</Key>

<Property Name="orderId" Type="Edm.Int64" Nullable="false"/>
<Property Name="customer_customerId" Type="Edm.String" 
    Nullable="false"/>
<Property Name="orderDate" Type="Edm.DateTime" Nullable="true"/>
<NavigationProperty Name="customer" 
    Relationship="NorthwindGridModel.Customer_orders"
    FromRole="Order" ToRole="Customer"/>

<NavigationProperty Name="orderDetails" 
    Relationship="NorthwindGridModel.Order_orderDetails" 
    FromRole="Order" ToRole="OrderDetail"/>
</EntityType>

エンティティーの作成時に、キーを変更してはいけません。 つまり、子エンティティーとその親とのキー・アソシエーションを変更する必要がある場合には、 子エンティティーを削除して、異なる親を使用して再作成する必要があります。 区画化されたデータ・グリッドでは、移動が複数の区画に関わる可能性が高いため、これには 2 つの異なるバッチ変更セットが必要になります。

操作のカスケード

EntityManager API では、柔軟なカスケード・ポリシーを使用できます。 パーシスト、削除、無効化、またはマージの各操作をカスケードするように、アソシエーションにマークを付けることができます。 このようなカスケード操作は、双方向アソシエーションの片側または両側で行うことができます。

OData プロトコルでは、アソシエーションの片側でのカスケード削除操作のみが許可されます。 CascadeType.REMOVE アノテーションおよび cascade-remove XML 属性は、1 対 1 双方向アソシエーションの両側または 1 対多アソシエーションの多側では定義できません。 以下の例で、有効な Cascade.REMOVE 双方向アソシエーションを示します。

@Entity(schemaRoot="true")
public class Customer {
    @Id String customerId;
    @OneToMany(mappedBy="customer", cascade=CascadeType.REMOVE)
    Order orders
}

@Entity
public class Order {
    @Id int orderId;
    @Id @ManyToOne Customer customer;
    java.util.Date orderDate;
}

結果の EDMX アソシエーションは、以下のようになります。

<Association Name="Customer_orders">
    <End Type="NorthwindGridModel.Customer" Role="Customer" 
        Multiplicity="1">
        <OnDelete Action="Cascade"/>
    </End>
    <End Type="NorthwindGridModel.Order" Role="Order" 
        Multiplicity="*"/>
</Association>