• No results found

Web Service Caching Using Command Cache

N/A
N/A
Protected

Academic year: 2021

Share "Web Service Caching Using Command Cache"

Copied!
15
0
0

Loading.... (view fulltext now)

Full text

(1)

Web Service Caching Using Command Cache

Introduction

Caching can be done at Server Side or Client Side. This article focuses on server side caching of web services using command cache.

This article will explain the same using an example. This article assumes some basic level of web services knowledge

The example was built and tested using the following software:

 RAD (Rational Application Developer 8)

 WAS (Web Sphere Application Server 7)

Requirement Scenario

1) We need to create a web service called FindDoctor. 2) FindDoctor web service should have a following method

ArrayList<Doctor> fetchDoctorList(String zipCode, String name, long ttlSec){ //return list of Doctor whose first name is name and location zip code is zipCode }

3) FindDoctorDAO class is used to retrieve required rows from database.

4) We need to cache the output of the FindDoctor web service at WAS (Websphere Application Server) using Zip Code and Doctor Name as cache IDs.

5) We need to allow client to dynamically specify the TTL (Time to Live) value for each cache entry.

6) Use Cache Monitor to view cache entries.

Implementation

1) Creating FindDoctor Web service

 Create a dynamic web project.

(2)

The following is the stub of the class

public class FindDoctor { //public constructor public FindDoctor(){ }

//web service method

public ArrayList<Doctor> fetchDoctorList(String zipCode, String name, long ttlsec){

return null; }

}

Note: Doctor is a java bean which our DAO (FindDoctorDAO) is returning.

2) Creating a class that extends CacheableCommandImpl

 CacheableCommandImpl class provides methods to cache data.

 The CacheableCommandImpl is an abstract class. In order to use caching make a concrete sub-class of it (FindDoctorCacheCmd) and override the isReadyToCallExecute() and performExecute() methods.

 The CacheableCommandImpl class provides life cycle for the cache-able object, it will call the isReadyToCallExecute() method of the extending class(FindDoctorCacheCmd) to check if the class is ready to execute. You can use this method to check if your data access part is ready. For eg, if you are accessing database you can check in this method whether your database connection is null and if you are talking to a web service then use this method to check if you can get a connection to the web service.  Only when the isReadyToCallExecute() method returns true, the flow will move

forward. If it returns false, exception will be thrown.

 The performExecute() method of the extending class is where we write our data access code(service logic). In our case we want to query the database for a list of doctors having the given name and residing in the given zip code.

(3)

public class FindDocCacheCmd extends CacheableCommandImpl{ //list of doctors from database

private ArrayList<Doctor> docList=null; //zip code where the doctor lives

private String zipCode; //name of the doctor

private String name; public FindDocCacheCmd(){ }

public FindDocCacheCmd(String zipCode,String name){ this.zipCode=zipCode;

this.name=name; }

@Override

public boolean isReadyToCallExecute() {

return (zipCode != null) && (name != null); }

@Override

public void performExecute() throws Exception { System.out.println("Not in Cache");

FindDoctorDAO docDAO=new FindDoctorDAO(); try { setDocList((ArrayList<Doctor>) docDAO.fetchDoctors(zipCode,name)); }catch (SQLException e) { e.printStackTrace(); } }

public void setDocList(ArrayList<Doctor> docList) { this.docList = docList;

}

public ArrayList<Doctor> getDocList() { return docList;

}

public String getZipCode(){ return zipCode;

}

public String getName() { return name;

}

public void setName(String name) { this.name = name;

} }

(4)

3) Creating cachespec.xml <?xml version="1.0"?>

<!DOCTYPE cache SYSTEM "cachespec.dtd"> <cache>

<cache-entry>

<class>command</class>

<sharing-policy>not-shared</sharing-policy>

<name>com.atech.training.cachecmd.FindDocCacheCmd</name> <cache-id>

<component type="method" id="getZipCode"> <required>true</required>

</component>

<component type="method" id="getName"> <required>true</required> </component> <timeout>150</timeout> <inactivity>100</inactivity> </cache-id> </cache-entry> </cache>

 Place the cachespec.xml file within the WEB-INF folder.

 You can also place a global cachespec.xml file in the application server properties directory.

 The cachespec.dtd and a sample cachespec.xml file are available in the application server’s properties directory (<APP-SERVER HOME>\properties).

 In the cachespec.xml first we are setting value of class to command, to let DynaCache know that we want to cache a custom java object.

 The value of name attribute is fully qualified name of the Java object.

 The cache-id element is used to define how to generate unique cache key for the cache-able object.

 In our case we wanted to use the zipCode and name (Doctor Name) as the caching id. Since the DynaCache can use getZipCode() and getName() methods to get the caching id, we configure it inside the component tag with type=”method” and id=”<METHOD NAME>

 The value of timeout element equal to 150. What this means is that the cache entry is valid only for 150 seconds. The value of inactivity is 100. This means that the cache entry will be removed if it is not accessed within 100s. The maximum period for which the cache entry exists in the cache is determined by the timeout and inactivity. The following explains this

(5)

Case 1: Timeout > Inactivity Timeout=60s

Inactivity=40s

Cache entry accessed within 40s will make it stay till 60s. After 60s (timeout) it will be removed. If it is not accessed within 40s (inactivity), it will be removed from the cache after 40s, even before the timeout. This means that inactivity takes precedence over timeout in this case.

Case 2: Timeout < Inactivity Timeout=30s

Inactivity=50s

Cache entry will stay till 30s only, whether it is accessed or not. This means that timeout takes precedence over inactivity in this case.

4) Calling execute() method in web service.

 Update the fetchDoctorList() method of our FindDoctor web service as follows //service method

public ArrayList<Doctor> fetchDoctorList(String zipCode, String name, long ttlsec){

FindDocCacheCmd findDoc=new FindDocCacheCmd (zipCode, name); try { System.out.println("Calling Execute"); findDoc.execute(); } catch (CommandException e) { e.printStackTrace(); } return findDoc.getDocList(); }

 The client of this web service on calling the fetchDoctorList() method will supply the zipCode, doctor name and time to live (timeout of the cache) value as input

parameters.

 Out of these parameters, zipCode and name are used to create a new object of the FindDocCacheCmd class.

FindDocCacheCmd findDoc=new FindDocCacheCmd (zipCode, name);  Call the execute() method of the created object.

 Have a look at FindDocCacheCmd class code. You will notice that we are not overriding the execute() method.

 The execute() method is provided by the super class and it is the place where the life cycle of cache is provided.

(6)

 The execute() method checks if there is object in cache for the current zipCode and name pair (zipCode and name together are the cache-id that we configured in the cachespec.xml). If yes, it will return the FindDocCacheCmd object from the cache. Otherwise it will call performExecute() method of FindDocCacheCmd object and once the result is returned it will store the instance of FindDocCacheCmd in DynaCache for the zipCode and name pair.

 After execute() method has been called, the FindDocCacheCmd object gets ready and we can call its getter methods to read the doctor list. i.e. getDocList();

5) Enabling dynamic caching

You will have to enable the dynamic caching on your server if it is not already enabled. You can use the WebSphere Application Server Administrative Console to do that.

Follow these steps

 Log into WebSphere Application Server Admininstrative Console

 Go to Servers -> WebSphere_Portal. If you are using a different server (say Websphere Application Server), select it.

 On the server details page expand Container Services and click on Dynamic Cache Service.

 On the Dynamic Cache Service page make sure that "Enable Service at server startup" check box is checked.

 To enable servlet caching, click Web Container Settings and check Enable Servlet Caching.

 To enable portlet caching, click Portlet Container Settings and check Enable Portlet Fragment Cache

 Save your changes and restart the server

Note: The web service is now ready for caching. You can test it using cache monitor.

Remember that the TTL for the cache entries is taken from the cashespec.xml file because we have not changed it programmatically in our implementation.

If cache monitor is already installed (which will not be the default) follow these steps to view the cache entries:

 Open http://<SERVER URL>/cachemonitor/ (eg. http://locahost:10000/cachemonitor).

(7)
(8)

 Click Cache Contents in the left menu

 Call the FindDoctor webservice from some client or use Generic Service Client.  Open Cache Monitor and Click Refresh Instances button under Cache Monitor

Note: The response is cached. If you call the web service with same zipCode and name arguments again (before cache entry’s TTL), the response will be taken from the cache. The timeout (seconds) field value is 150 which we configured in

(9)

6) Allowing the Client to customize the TTL values for each cache entry

 For this to happen we need to first update our FindDocCacheCmd class and FindDoctor class as follows.

Updating FindDocCacheCmd class  Add a private class variable

private long cacheTimeOut;

 Generate setter and getter for cacheTimeOut

public void setCacheTimeOut(long cacheTimeOut) { this.cacheTimeOut = cacheTimeOut; }

public long getCacheTimeOut() { return cacheTimeOut; }

 Add the following method

public void setExpTime(long ttlsec){

this.getEntryInfo().setTimeLimit((int) ttlsec); this.getEntryInfo().setInactivity((int) ttlsec); }

 Update the performExecute() method.

public void performExecute() throws Exception { System.out.println("Not in Cache");

setExpTime(getCacheTimeOut());

FindDoctorDAO docDAO=new FindDoctorDAO(); try { setDocList((ArrayList<Doctor>) docDAO.fetchDoctors(zipCode)); } catch (SQLException e) { e.printStackTrace(); } }

(10)

Updating FindDoctor class

 Update fetchDoctorList() method so it look as follows

public ArrayList<Doctor> fetchDoctorList(String zipCode, String name, long ttlsec){

FindDocCacheCmd findDoc=new FindDocCacheCmd(zipCode, name);

try {

System.out.println("Calling Execute");

findDoc.setCacheTimeOut(ttlsec); findDoc.execute(); }catch (CommandException e) { e.printStackTrace(); } return findDoc.getDocList(); }

 Save and Generate the Web Service Again.  Open Cache Monitor.

 Call the FindDoctor webservice from a client or use Generic Service Client.  Give ttlsec value this time, say 60.

 In Cache Monitor click Refresh Instances button under Cache Monitor

Note: The value of Timeout(seconds) field is 60, the one we passed as ttlsec parameter instead of 150 which we initially specified in cachespec.xml.

(11)

APPENDIX:

HOW TO INSTALL DYNAMIC CACHE MONITOR IN WEBSPHERE?

(12)
(13)
(14)
(15)

To see the dynamic cache monitor, make sure that the websphere server is running and go to the url

http://<server url>/cachemonitor/

Authors: Yawar Khan Ascendant Technology India. (Chennai) Sankar Krishnan.S Ascendant Technology India. (Chennai)

References

Related documents

Thus for these activities, constraint set 2.6 implies that a train can only depart on a track of an open track section if a train has departed on the same track in the same

Old Habit: Paper CRF Process Primary Investigator Source Document CRC CRFs CRFs DB1 Double Data Entry Master Clinical 6 Query Report Form Site Sponsor Query Report Form CDM

gliricidia, trichantera, indi- gofera, calliandra, papaya leaves, cassava leaves, leucaena, rapeseed meal, corn gluten feed, soybean meal, copra meal, palm kernel meal, fish and

The suspension offers a high level of comfort with low road noise and tire vibration while ensuring agile driving dynamics – the basis for driving enjoyment.. A new 4-link front

We investigated how an increase in oxygen partial pressure in healthy young volunteers affects pulmonary ventilation and perfusion measured by thoracic electrical

50% of inspiratory displacement divided by TA expiratory displacement rate at 50% of expiratory displacement; IQR, interquartile range; MWU, Mann-Whitney-U; rCT, relative

Bland, Marghuretta D.; Sturmoski, Audra; Whitson, Michelle; Connor, Lisa Tabor; Fucetola, Robert P.; Huskey, Thy; Corbetta, Maurizio; and Lang, Catherine E., &#34;Prediction

than the rights of the parties addressed in Day,” and the Court ultimately deferred to the Texas Supreme Court to “recognize and pronounce such. an expansion” of the holding in Day