概要
PlayReady テスト サーバーには、さまざまなサーバー例外をプログラムでトリガーするための特別な機能が含まれています。 この機能を使用すると、クライアント開発者は、運用環境でのライセンス取得中に発生する可能性があるさまざまなエラー条件に対して、デバイスとアプリケーションがどのように応答するかをテストできます。
サーバー例外テスト
クライアント開発者は、これらのサーバー例外コマンドを使用して、実装でのエラー処理を検証できます。 これには、デバイスの失効、内部サーバー エラー、プロトコルの不一致、ドメイン関連の例外などのテスト シナリオが含まれます。
トランザクションの例
サーバー例外のしくみの例を次に示します。
要求 URL:
http://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(errorcode:0x8004c065)
サーバーの応答:
HTTP/1.1 500 Internal Server Error
Cache-Control: private
Content-Length: 764
Content-Type: text/xml; charset=utf-8
<?xml version="1.0" encoding="utf-8" ?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>
System.Web.Services.Protocols.SoapException: Device Certificate Revoked.
at Microsoft.Media.Drm.RightsManager.ConvertRmServerException(RMServerException ex)
at Microsoft.Media.Drm.RightsManager.AcquireLicense(XmlDocument challenge)
</faultstring>
<faultactor>http://prtsprod-rightsmanager.azurewebsites.net/rightsmanager.asmx?cfg=(errorcode:0x8004c065)</faultactor>
<detail>
<Exception>
<StatusCode>0x8004c065</StatusCode>
</Exception>
</detail>
</soap:Fault>
</soap:Body>
</soap:Envelope>
例外パラメーター
ジェネリック例外パラメーター
| パラメーター | 説明 | 例の URL |
|---|---|---|
errorcode:XXXXXXXX |
特定の例外で応答するようにサーバーに要求する | http://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(errorcode:0xXXXXXXXX) |
デバイスとクライアントの例外
失効したデバイス証明書
| パラメーター | 例外 | 説明 |
|---|---|---|
errorcode:8004C065 |
DRM_E_DEVCERT_REVOKED |
サーバーがライセンスを失効したクライアント デバイスに配信できない |
例:
http://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(errorcode:0x8004c065)
使用法: クライアントがデバイス失効シナリオを処理する方法をテストします。
サーバー内部例外
内部サーバー エラー
| パラメーター | 例外 | 説明 |
|---|---|---|
errorcode:8004C600 |
DRM_E_SERVER_INTERNAL_ERROR |
サーバーが内部サーバー例外をスローする |
例:
http://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(errorcode:0x8004c600)
使用法: サーバー側の内部エラーに対するクライアントの回復性をテストします。
無効なメッセージ
| パラメーター | 例外 | 説明 |
|---|---|---|
errorcode:8004C601 |
DRM_E_SERVER_INVALID_MESSAGE |
サーバーに送信された要求が無効でした |
例:
http://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(errorcode:0x8004c601)
使用法: 形式が正しくない要求応答のクライアント処理をテストします。
プロトコル バージョンの不一致
| パラメーター | 例外 | 説明 |
|---|---|---|
errorcode:8004C60B |
DRM_E_SERVER_PROTOCOL_VERSION_MISMATCH |
要求で指定されたプロトコル バージョンがサーバーでサポートされていませんでした |
例:
http://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(errorcode:0x8004c60b)
使用法: サポートされていないプロトコル バージョンでクライアントの動作をテストします。
サービス固有の例外
| パラメーター | 例外 | 説明 |
|---|---|---|
errorcode:8004C604 |
DRM_E_SERVER_SERVICE_SPECIFIC |
サーバーがサービス固有の例外をスローする (通常はライセンス ハンドラーから) |
例:
http://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(errorcode:0x8004c604)
使用法: サービス固有のエラーのクライアント処理をテストします。
プロトコルとリダイレクトの例外
プロトコル リダイレクト
| パラメーター | 例外 | 説明 |
|---|---|---|
errorcode:8004C60D |
DRM_E_SERVER_PROTOCOL_REDIRECT |
プロトコルにリダイレクトがある |
例:
http://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(errorcode:0x8004c60d)
使用法: サーバー リダイレクトのクライアント処理をテストします。
Domain-Related 例外
ドメインが必要
| パラメーター | 例外 | 説明 |
|---|---|---|
errorcode:8004C605 |
DRM_E_SERVER_DOMAIN_REQUIRED |
サーバーはクライアントから標準ライセンス要求を受け取り、ドメイン バインド ライセンスを受け取るためにクライアントがドメインに参加する必要がある |
例:
http://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(errorcode:0x8004c605)
使用法: ドメイン参加シナリオとクライアント ドメイン認識をテストします。
ドメインの更新
| パラメーター | 例外 | 説明 |
|---|---|---|
errorcode:8004C606 |
DRM_E_SERVER_RENEW_DOMAIN |
サーバーは、古いドメイン バージョンを含むドメイン証明書を使用してクライアントから要求を受信しました。 クライアントがドメイン証明書を更新する必要があります |
例:
http://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(errorcode:0x8004c606)
使用法: ドメイン証明書の更新プロセスをテストします。
デバイスの制限に達しました
| パラメーター | 例外 | 説明 |
|---|---|---|
errorcode:8004C602 |
DRM_E_SERVER_DEVICE_LIMIT_REACHED |
サーバーはクライアントをドメイン アカウントに追加する予定でしたが、アカウントは既にデバイスの数の制限に達しています |
例:
http://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(errorcode:0x8004c602)
使用法: ドメイン デバイス制限のクライアント処理をテストします。
ドメイン メンバーではない
| パラメーター | 例外 | 説明 |
|---|---|---|
errorcode:8004C60A |
DRM_E_SERVER_NOT_A_MEMBER |
サーバーはクライアントから有効なドメイン バインド ライセンス要求を受け取りましたが、クライアントは以前にサービスによってドメインから削除されています |
例:
http://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(errorcode:0x8004c60a)
使用法: ドメインから削除された場合のクライアント動作をテストします。
不明なアカウント ID
| パラメーター | 例外 | 説明 |
|---|---|---|
errorcode:8004C60C |
DRM_E_SERVER_UNKNOWN_ACCOUNTID |
サーバーは、特定のアカウント ID に対するドメイン バインド ライセンス要求をクライアントから受信しましたが、この ID はサービスに対して不明です |
例:
http://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(errorcode:0x8004c60c)
使用法: 不明なドメイン アカウント シナリオのクライアント処理をテストします。
テスト シナリオ
基本的な例外テスト
async function testServerExceptions() {
const exceptions = [
{ name: 'Device Revoked', code: '0x8004c065' },
{ name: 'Internal Error', code: '0x8004c600' },
{ name: 'Invalid Message', code: '0x8004c601' },
{ name: 'Protocol Mismatch', code: '0x8004c60b' }
];
const results = [];
for (const exception of exceptions) {
try {
const url = `http://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(errorcode:${exception.code})`;
const response = await testLicenseAcquisition(url);
results.push({
test: exception.name,
result: 'UNEXPECTED_SUCCESS',
error: 'Expected exception but got success'
});
} catch (error) {
results.push({
test: exception.name,
result: 'EXPECTED_EXCEPTION',
errorCode: error.statusCode,
message: error.message
});
}
}
return results;
}
ドメイン例外テスト
async function testDomainExceptions() {
const domainExceptions = [
{ name: 'Domain Required', code: '0x8004c605' },
{ name: 'Renew Domain', code: '0x8004c606' },
{ name: 'Device Limit Reached', code: '0x8004c602' },
{ name: 'Not a Member', code: '0x8004c60a' },
{ name: 'Unknown Account', code: '0x8004c60c' }
];
const results = [];
for (const exception of domainExceptions) {
try {
const url = `http://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(errorcode:${exception.code})`;
await testLicenseAcquisition(url);
results.push({
test: exception.name,
result: 'FAIL',
reason: 'Expected domain exception but got success'
});
} catch (error) {
results.push({
test: exception.name,
result: 'PASS',
exceptionType: exception.name,
statusCode: error.statusCode
});
}
}
return results;
}
クライアント堅牢性テスト
async function testClientRobustness() {
// Test how client handles rapid exception scenarios
const rapidTests = [
'0x8004c065', // Device revoked
'0x8004c600', // Internal error
'0x8004c601', // Invalid message
'0x8004c60b' // Protocol mismatch
];
const startTime = Date.now();
const promises = rapidTests.map(code => {
const url = `http://test.playready.microsoft.com/service/rightsmanager.asmx?cfg=(errorcode:${code})`;
return testLicenseAcquisitionWithTimeout(url, 5000);
});
const results = await Promise.allSettled(promises);
const endTime = Date.now();
return {
totalTime: endTime - startTime,
results: results.map((result, index) => ({
errorCode: rapidTests[index],
status: result.status,
handled: result.status === 'rejected' // We expect rejections
}))
};
}
クライアント実装ガイドライン
例外処理のベスト プラクティス
class PlayReadyExceptionHandler {
handleLicenseAcquisitionError(error) {
switch (error.statusCode) {
case 0x8004C065: // Device revoked
return this.handleDeviceRevoked();
case 0x8004C600: // Internal server error
return this.handleServerError(error);
case 0x8004C601: // Invalid message
return this.handleInvalidMessage(error);
case 0x8004C60B: // Protocol version mismatch
return this.handleProtocolMismatch(error);
case 0x8004C605: // Domain required
return this.handleDomainRequired(error);
case 0x8004C606: // Renew domain
return this.handleDomainRenewal(error);
default:
return this.handleUnknownError(error);
}
}
handleDeviceRevoked() {
// Device is revoked - cannot proceed
throw new Error('Device has been revoked and cannot play protected content');
}
handleServerError(error) {
// Retry with exponential backoff
return this.retryWithBackoff(error.originalRequest);
}
handleDomainRequired(error) {
// Initiate domain joining process
return this.joinDomain(error.domainServiceUrl);
}
handleDomainRenewal(error) {
// Renew domain certificate
return this.renewDomainCertificate(error.domainServiceUrl);
}
}
C# 例外処理
public class PlayReadyExceptionHandler
{
public async Task<bool> HandleLicenseException(Exception ex)
{
if (ex is SoapException soapEx)
{
var statusCode = ExtractStatusCode(soapEx);
switch (statusCode)
{
case 0x8004C065: // Device revoked
return HandleDeviceRevoked();
case 0x8004C600: // Internal server error
return await HandleServerError(soapEx);
case 0x8004C605: // Domain required
return await HandleDomainRequired(soapEx);
case 0x8004C606: // Renew domain
return await HandleDomainRenewal(soapEx);
default:
return HandleUnknownError(soapEx);
}
}
return false;
}
private uint ExtractStatusCode(SoapException soapEx)
{
// Extract status code from SOAP fault detail
var detail = soapEx.Detail;
var statusNode = detail?.SelectSingleNode("//StatusCode");
if (statusNode != null && uint.TryParse(statusNode.InnerText.Replace("0x", ""),
NumberStyles.HexNumber, null, out uint statusCode))
{
return statusCode;
}
return 0;
}
}
検証とテスト
予期される動作
サーバー例外を使用してテストする場合は、クライアントが次の点を検証します。
- 例外を正しく解析する - エラー コードとメッセージを正しく抽出する
- 正常に処理 する - 例外でクラッシュまたはハングしない
- ユーザー フィードバックを提供 する - ユーザーに適切なエラー メッセージを表示する
- 再試行ロジックを実装 する - バックオフを使用して適切なエラーを再試行する
- ドメイン操作のサポート - ドメイン関連の例外を正しく処理する
テスト検証チェックリスト
- [ ] クライアントが例外の種類を正しく識別する
- [ ] 適切なユーザー メッセージが表示される
- [ ] 任意の例外の種類でクライアントがクラッシュしない
- [ ] 再試行ロジックは回復可能なエラーに対して機能します
- [ ] ドメイン参加/更新プロセスが正しくトリガーされる
- [ ] デバイスの失効は安全に処理されます
- [ ] エラー条件下でもパフォーマンスは引き続き許容されます
ベスト プラクティス
クライアント開発
- 包括的なエラー処理 - 文書化されたすべての例外の種類を処理する
- ユーザー エクスペリエンス - 明確で実用的なエラー メッセージを提供する
- 再試行戦略 - 一時的なエラーに対して適切な再試行ロジックを実装する
- セキュリティ - デバイスの失効がコンテンツ アクセスを防ぐ
- テスト - 開発中にすべての例外シナリオをテストする
エラーの回復
- 正常な低下 - 可能な場合は操作を続行する
- 明確なコミュニケーション - 問題と解決策をユーザーに通知する
- 自動回復 - 必要に応じて自動解決を試みます
- フォールバック オプション - 代替コンテンツまたはサービスを提供する
- ログ 記録 - デバッグと分析の例外をログに記録する
関連ドキュメント
- PlayReady テスト サーバー サービス - 主要なテスト サーバー機能
- クエリ文字列構文 - パラメーター構文リファレンス
- 出力保護のテスト - 出力保護テスト
- PlayReady テスト サーバー - サーバーの完全なドキュメント
サポート リソース
ビジネス クエリ
- 電子メール: playready@microsoft.com
操作クエリ
- Web サイト: http://wmlalicensing.com/
- 電子メール: ipla@microsoft.com
テクニカル サポート
- サポート ポータル: PlayReady テクニカル サポート
トレーニング情報
- 電子メール: plyrdyev@microsoft.com