Web サービス・クライアント・キャッシュは、動的キャッシュ・サービスの一部であり、リモート Web サービスからの応答をキャッシュに入れて、 Web サービス・クライアントのパフォーマンスを高めるために使用されます。Web サービス・クライアント・キャッシュを構成すると、特定の時間のリモート Web サービスからの応答をキャッシュに入れることによって、アプリケーション・サーバーのパフォーマンスを改善することができます。
Web サービス・クライアント・キャッシュを使用可能にすると、特定の時間のリモート Web サービスからの応答を保管する動的キャッシュ・サービスを使用することによって、システムのパフォーマンスを改善することができます。 リモート Web サービスから応答が戻されると、その応答はアプリケーション・サーバー上のクライアント・キャッシュに保管されます。 同じリモート Web サービスに対して行われた同一の要求はすべて、 指定された期間の間、キャッシュから応答されます。 Web サービス・クライアント・キャッシュは、主に時間ベースの無効化に依存します。これは、ターゲット Web サービスが、エンタープライズ・ネットワークの外側にあって、クライアント・キャッシングを認識できない可能性があるためです。 そのため、ユーザーは時間の長さをキャッシュ内に指定し、 キャッシュ・エントリー ID の作成規則をクライアント・アプリケーションのキャッシュ内に指定することができます。
Web サービス・クライアント・キャッシュは、 アプリケーション・サーバー上で Java API for XML-Based Remote Procedure Calls (JAX-RPC) ハンドラーとして提供されます。 この JAX-RPC キャッシュ・ハンドラーは、 アプリケーション・クライアントから流れてくる SOAP 要求をインターセプトします。 さらに JAX-RPC キャッシュ・ハンドラーは、 ターゲット Web サービスに基づいてキャッシュ・ポリシーを識別します。 いったんポリシーが見つかると、すべてのキャッシュ ID 規則は、有効な規則が検出されるまで、1 つずつ評価されます。
<definitions targetNamespace="http://TradeSample.com/" xmlns:tns="http://TradeSample.com/" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <message name="getQuoteRequest"> <part name="symbol" type="xsd:string"/> </message> ..... ..... <binding name="SoapBinding" type="tns:GetQuote"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="getQuote"> <soap:operation soapAction=""/> <input name="getQuoteRequest"> <soap:body namespace="http://TradeSample.com/" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </input> ...... </operation> </binding> <service name="GetQuoteService"> <port binding="tns:SoapBinding" name="SoapPort"> <soap:address location="http://TradeSample.com:9080/service/getquote"/> </port> </service> </definitions>強調表示しているテキストは、キャッシュ・ポリシーを書き込む際に使用される値を示しています。
すべての Web サービス・クライアント・キャッシュ・ポリシーに class JAXRPCClient がなければなりません。各キャッシュ・エントリーの name エレメントは、 WSDL ファイルに定義されるターゲット・エンドポイント・ロケーションです。 port エレメントにある <soap:address location=".."/> タグを見付けることによって、WSDL ファイルのこのアドレスを見付けることができます。この例の WSDL ファイルでは、 アドレスは http://TradeSample.com:9080/service/getquote です。 次のオプションの 1 つを使用してキャッシュ・ポリシーの残りを作成します。
<cache> <cache-entry> <class>JAXRPCClient</class> <name>http://TradeSample.com:9080/service/getquote</name> <cache-id> <component id="hash" type="SOAPEnvelope"/> <timeout>60</timeout> </cache-id> </cache-entry> </cache>
SOAPEnvelope のハッシュ計算に基づいてキャッシュ ID を作成するために、component 属性に注意します。 このサンプルのキャッシュ ID は、http://TradeSample.com:9080/service/getquote:Hash=xxxHashSoapEnvelope のように生成されます。
<cache> <cache-entry> <class>JAXRPCClient</class> <name>http://TradeSample.com:9080/service/getquote</name> <cache-id> <component id="urn:stock:getQuote" type="SOAPHeaderEntry"/> </cache-id> </cache-entry> </cache>
このキャッシュ ID は、キャッシュのエントリーの要求を識別するために、SOAP ヘッダーの特別な情報を使用することによって作成されます。type を SOAPHeaderEntry と指定し、id を WSDL ファイルの binding エレメントにある operation 名と指定します。 このサンプルのキャッシュ ID は、http://TradeSample.com:9080/service/getquote:urn:stock:getQuote=IBM のように生成されます。
以下は、SOAP ヘッダーを使用してクライアントによって生成される SOAP 要求の例です。
POST /wsgwsoap1/soaprpcrouther HTTP/1.1 SOAPAction: "" Context-Type: text/xml; charset=utf-8 User-Agent: Java/1.4.1 Host: localhost Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 Connection: keep-alive Content-Length: 645 <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Header> <getQuote soapenv:actor="com.ibm.websphere.cache" xmlns="urn:stock">IBM</getQuote> </soapenv:Header> <soapenv:Body soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding"> <getQuote xmlns="urn:ibmwsgw#GetQuoteSample"> <symbol xsi:type="xsd:string">IBM</symbol> </getQuote> </soapenv:Body> </soapenv:Envelope>
<cache> <cache-entry> <class>JAXRPCClient</class> <name>http://TradeSample.com:9080/service/getquote</name> <cache-id> <component id="" type="operation"> <value>http://TradeSample.com/:getQuote</value> </component> <component id="symbol" type="part"/> </cache-id> </cache-entry> </cache>
この例はオペレーションおよび要求パラメーターを使用しています。operation は binding エレメントにある WSDL ファイルのメソッド名または Document/Literal Invocation (DII) のメソッド名にすることができます。オペレーションのネーム・スペースが定義されている場合、 値は namespaceOfOperation:nameOfOperation としてフォーマット設定されている必要があります。 part タイプは、要求パラメーターまたは DII 呼び出しの要求パラメーターとして、WSDL ファイルの message エレメントで定義することができます。 その id 属性はパーツまたはパラメーター名で、value はパーツまたはパラメーターの値です。 オペレーションおよび要求パラメーターを使用することによって生成されるキャッシュ ID は、http://TradeSample.com:9080/service/getquote:operation=http://TradeSample.com/:getQuote/symbol=IBM です。
以下は、オペレーションおよびパーツを使用してクライアントが生成する SOAP 要求の例です。
POST /wsgwsoap1/soaprpcrouter HTTP/1.1 SOAPAction:"" Content-Type: text/xml/charset=utf-8 User-Agent: Java/1.4.1 Host: localhost Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 Connection: keep-alive Current-Length: 645 <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"> <getQuote xmlns="urn:ibmwsgw#GetQuoteSample"> <symbol xsi:type="xsd:string">IBM</symbol> </getQuote> </soapenv:Body> </soapenv:Envelope>
カスタム Java コードを使用してキャッシュ ID を作成する場合は、com.ibm.websphere.cache.webservices.IdGenerator パッケージで定義されている IdGenerator インターフェースをインプリメントする ID ジェネレーターの Java クラスを 作成して、idgenerator タグを使用して cachespec.xml ファイルに作成するクラスに参照を追加する必要があります。
com.ibm.websphere.cache.webservices.MetaDataGenerator パッケージをインプリメント すると、metadatagenerator タグを使用して、タイムアウト、優先順位、および依存関係 ID などの キャッシュ・メタデータをキャッシュ・エントリーに割り当てることができます。
com.ibm.websphere.cache.webservices.InvalidationGenerator インターフェースをインプリメントし、cachespec.xml ファイル内の invalidationgenerator タグを使用してキャッシュ ID を生成し、キャッシュ内のエントリーを無効にします。 無効化ジェネレーターで生成される ID は、キャッシュ ID または依存関係 ID です。
例えば、SampleIdGeneratorImpl という名の ID ジェネレーターのクラス、SampleMetaDataGeneratorImpl という名の メタデータ・ジェネレーターのクラス、および SampleInvalidationGeneratorImpl という名の無効化ジェネレーターのクラス を作成する場合、cachespec.xml ファイルは以下を含むことがあります。
<cache-entry> <class>JAXRPCClient</class> <name>http://TradeSample.com:9080/service/getquote</name> <cache-id> <idgenerator>com.mycompany.SampleIdGeneratorImpl</idgenerator> <metadatagenerator> com.mycompany.SampleMetaDataAndInvalidationGeneratorImpl </metadatagenerator> <timeout>60</timeout> </cache-id> <invalidation>http://TradeSample.com:9080/service/GetQuote <invalidationgenerator> com.mycompany.SampleMetaDataAndInvalidationGeneratorImpl </invalidationgenerator> </invalidation> </cache-entry>
String getId(javax.xml.rpc.handler.soap.SOAPMessageContext messageContext)
以下は、SampleIdGeneratorImpl.java クラスの例です。
public class SampleIdGeneratorImpl implements IdGenerator { //The SampleIdGenerator class builds cache keys using SOAP header entries public String getId(javax.xml.rpc.handler.soap.SOAPMessageContext messageContext) { .... // retrieve SOAP header entries from SOAPMessage SOAPHeader sh = soapEnvelope.getHeader(); if (sh != null) { Iterator it = sh.examineHeaderElements("com.mycompany.actor"); while (it.hasNext()) { SOAPHeaderElement element = (SOAPHeaderElement)it.next(); Name name = element.getElementName(); String headerEntryName = name.getLocalName(); if (headerEntryName.equals("getQuote")){ String sNamespace = element.getNamespaceURI(""); if (sNamespace != null && !sNamespace.equals("")) { headerEntryName = sNamespace + ":" + headerEntryName; String quotes = element.getValue(); } ... ... // create a method "parseAndSort" to parse and sort quotes // By parsing and sorting quotes, you avoid duplicate cache // entries. // quotes e.g. IBM,CSCO,MSFT,INTC // to return a cache key "urn:stock:getQuote=CSCO,IBM,INTC,MSFT" String sortQuotes = parseAndSort(quotes); cacheKey = headerEntryName + "=" + sortQuotes; } } return cacheKey; } }
このサンプルのキャッシュ ID は http://TradeSample.com:9080/service/getquote:urn:stock:symbol=CSCO,IBM,INTC,MSFT のように生成されます。
SampleMetaDataAndInvalidationGeneratorImpl クラスは、com.websphere.cache.webservices.MetaDataGenerator インターフェースおよび com.websphere.cache.webservices.InvalidationGenerator インターフェースを インプリメントするカスタム Java クラスです。 SampleMetaDataAndInvalidationGeneratorImpl クラスには、setMetaData メソッドおよび getInvalidationIds メソッドが 含まれています。 1 つの大きなクラスの代わりに、2 つの小さなクラスをセットアップすることもできます。 例えば、メタデータ・ジェネレーターに対して 1 つのクラスを作成し、無効化ジェネレーターに対して異なる クラスを作成します。 setMetaData メソッドおよび getInvalidationIds メソッドのメソッド・プロトタイプは、以下のとおりです。
void setMetaData (javax.xml.rpc.handler.soap.SOAPMessageContext messageContext, com.ibm.websphere.cache.webservices.JAXRPCEntryInfo entryInfo) String[] getInvalidationIds (javax.xml.rpc.handler.soap.SOAPMessageContext messageContext)
SampleMetaDataAndInvalidationGeneratorImpl.java クラスの例は、以下のとおりです。
public class SampleMetaDataAndInvalidationGeneratorImpl implements MetaDataGenerator, InvalidationGenerator { //assigns time limit, and priority metadata public void setMetadata(javax.xml.rpc.handler.soap.SOAPMessageContext messageContext, com.ibm.websphere.cache.webservices.JAXRPCEntryInfo entryInfo) { .... // retrieve SOAP header entries from SOAPMessage SOAPHeader sh = soapEnvelope.getHeader(); if (sh != null) { Iterator it = sh.examineHeaderElements("com.mycompany.actor"); while (it.hasNext()) { SOAPHeaderElement element = (SOAPHeaderElement)it.next(); Name name = element.getElementName(); String headerEntryName = name.getLocalName(); if (headerEntryName.equals(“metadata”)) { // retrieve each metadata element and set metadata entryInfo.setTimeLimit(timeLimit); entryInfo.setPriority(priority); } } } //builds invalidation ids using SOAP header. public String[] getInvalidationIds(javax.xml.rpc.handler.soap.SOAPMessageContext messageContext) { .... // retrieve SOAP header entries from SOAPMessage String[] invalidationIds = new String[1]; SOAPHeader sh = soapEnvelope.getHeader(); if (sh != null) { Iterator it = sh.examineHeaderElements("com.mycompany.actor"); while (it.hasNext()) { SOAPHeaderElement element = (SOAPHeaderElement)it.next(); Name name = element.getElementName(); String headerEntryName = name.getLocalName(); if (headerEntryName.equals("invalidation")) { String sNamespace = element.getNamespaceURI(""); if (sNamespace != null && !sNamespace.equals("")) { headerEntryName = sNamespace + ":symbol"; String quotes = element.getValue(); } ... ... // create a method "parseAndSort" to parse and sort quotes // By parsing and sorting quotes, you avoid duplicate cache // entries. // quotes e.g. SUNW,NT // to return a cache key "urn:stock:symbol=NT,SUNW" String sortQuotes = parseAndSort(quotes); invalidationIds[0] = headerEntryName + "=" sortQuotes; } } return invalidationIds; } }
http://TradeSample.com:9080/service/getquote:urn:stock:symbol=NT,SUNW
カスタム Java コードを使用した場合にクライアントが作成する SOAP 要求の例は以下のとおりです。
POST /wsgwsoap1/soaprpcrouter HTTP/1.1 SOAPAction: "" Context-type: text/xml, charset=utf-8 User-Agent: Java/1.4.1 Host: localhost Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 Connection: keep-alive Content-Length:645 <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Header> <getQuote soapenv:actor="com.mycompany.actor" xmlns="urn:stock">IBM,CSCO,MSFT,INTC</getQuote> <metaData soapenv:actor="com.mycompany.actor" xmlns="urn:stock"> <priority>10</priority> <timeLimit>30000</timeLimit> </metaData> <invalidation soapenv:actor="com.mycompany.actor" xmlns="urn:stock">SUNW, NT</invalidation> </soapenv:Header> <soapenv:Body soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding"> <getQuote xmlns="urn:ibmwsgw#GetQuoteSample"> <symbol xsi:type="xsd:string">IBM,CSCO,MSFT,INTC</symbol> </getQuote> </soapenv:Body> </soapenv:Envelope>