PageBox |
|
|
|
|
|
Presentation | Install | User guide | Developer guide | Programming | Port | Repository | PageBox | Release notes |
Repository of PageBox for JavaForewordObjectiveThis document presents the implementation of the PageBox repository. To present the design we use a representation that loosely follows UML. AudienceProgrammers who want:
This documentation assumes some knowledge of UML, Java and J2EE. Design choices
Use casesThe Repository interfaces with:
PublisherThe publisher – maybe the author of an Application – packages a PageBox archive and uploads this archive on a Repository.
The publisher can publish or unpublish a Web archive. In case of new archive:
In case of archive update:
The unpublication triggers the undeployment of the archive on every PageBox where it was deployed. SubscriberThe subscriber registers one or more Pageboxes as agents interested by all (normal subscription) or some (archive subscription) archives available on a Repository.
The subscriber can subscribe or unsubscribe a PageBox. This use case can be divided in two cases:
A normal subscription triggers the deployment of all archives published on the Repository onto the subscribed PageBox. The selection of an archive for an archive-subscribed pagebox triggers the deployment of this archive onto the archive-subscribed PageBox. The unselection of an archive for an archive-subscribed pagebox triggers the undeployment of this archive from the archive-subscribed PageBox. The unsubscription of a PageBox triggers the undeployment of all archives deployed from the Repository. PageBox
The repository calls a Deploy Web service to deploy and undeploy Web archives on PageBoxes. When the deployment is triggered by a publication the archive must be deployed on all subscribers. In that case some PageBoxes can act as archive deployment relays. See the Grid API V2 documentation for more information about the algorithm.
In the diagram the Repository must deploy an archive on PageBox1, PageBox2 and PageBox3. The Repository calls the Deploy Web service of PageBox1. PageBox1 acts as a Relay and:
Once it has received the PageBox1 deployment status the Repository calls the Deploy Web service of PageBox2. Through that mechanism deployments on PageBox2 and PageBox3 happen in parallel. PublishSequence diagramsUpload
publish.jsp displays a form that displays the archives already published by the Publisher. The Publisher enters the archive path and triggers an upload. PublishArchive handles the upload request, stores the uploaded archive and calls the add method of RepoArchs. Then PublishArchive forwards the HTTP request to publish.jsp to display the updated archive list. Delete/force
publish.jsp displays a form that displays the archives already published by the Publisher. The Publisher selects an archive to delete. Publish handles the delete request and calls the delete method of RepoArchs. Then Publish forwards the HTTP request to publish.jsp to display the updated archive list. The difference between delete and force is that if the undeployment failed the archive is not removed from a subscriber in case of delete whereas it is removed in case of force. Class diagram
publish.jsp is the view and displays the content of the PublishBean model. RepoArchs reads archives.xml in its init method and rewrites archives.xml in its save method. RepoArchs updates the PublishBean model. Publish and PublishArchive are the controller. They interpret the user request and invoke RepoArchs. RepoArchsIf it doesn’t exist yet, RepoArchs instantiates and initializes a RepoArchs singleton in its public methods, add, delete and getArchives, which are static. The initialization takes place in the init method. init creates a PublishBean object and restores archives.xml in a archives member variable of this PublishBean instance using the ArchiveHandler SAX handler. archives is a TreeMap whose key is the archive name and value is an Archive object:
Where:
Public static methods invoke private methods of RepoArchs:
These methods handle the creation of delta jardiff archives (aadd) and the deletion of archives (adelete)
aaddIn case of archive creation aadd moves the uploaded archive from Uploaddir to Downloaddir. Then aadd creates a new Archive object and stores it in the PublishBean’s archives. aadd checks if the uploaded archive is a jardiff with a checkDelta method. If it is the case aadd sets the archive as a delta. In case of archive update aadd calls a diff method to create a jardiff between the old version of the archive stored in Downloaddir and the new version stored in Uploaddir. Then it replaces the old version by the new version. Next aadd updates the archives map. If the uploaded archive is a jardiff, diff doesn’t create a new jardiff, just replace the old version by the new version and sets the archive as a delta. In both cases aadd calls the add method of RepoSubs and RepoASubs to deploy the archive on the subscribers and update their archive list. jardiff is a format defined in the JNLP specification used in products such as Java WebStart. A jardiff is a Java archive that contains:
Note: Jardiff uploads are handled like archive creations. The publisher cannot mix modes: When an archive has been created with a full load it must be updated with full loads. When a delta has been created it must be updated with jardiff. adeleteadelete calls the delete method of RepoSubs and RepoASubs to undeploy the archive on its subscribed and archive-subscribed PageBoxes. Then adelete deletes the archive in Downloaddir and its jardiff in Deltadir. Eventually if the archive was successfully removed from all subscribed PageBoxes adelete removes the archive entry from the PublishBean’s archives. Otherwise adelete set the archive entry in pending remove state. deletePendingdeletePending is called in a SaveSubs method called checkArchive on behalf of retryDeploy in the Retry thread when all PageBox that subscribed the archive have successfully removed deletePending removes the archive entry from the PublishBean’s archives. PublishBeangetArchivesPublishBean implements a static getArchives method, which is called by publish.jsp. getArchives retrieves the RepoArchs instance and then the embedded PublishBean instance. Next getArchives determines if the user requested a date sort with getParameter("date"): Two buttons are defined on publish.jsp to allow sorting by archive name or by publication date. When the user clicks on the date button a date parameter is set. Eventually getArchives calls the getArchs method of PublishBean. getArchsgetArchs returns an HTML string that contains a table row per archive published on the Repository by the same user as the requestor or by any user when the user is in a pagebox-admin role. These rows can be sorted either by archive name or by publication date. getArchs uses the archives map, which is sorted by archive name. In case of sort by date getArchs populates a temporary TreeMap tm with the content of archives. The tm key is a DateArch object. The DateArch class embeds the publication date and the archive name. DateArch implements the Comparable interface in a consistent with equals way. To do this DateArchs implements the compareTo method of the Comparable interface and overrides the equals method.
In case of date sort getArchs implements a sort of toggle. The first time the user clicks on date a order boolean is false, which means that archives must be sorted the most recent first. Then getArchs writes a hidden order field in the HTML string. The next time the user clicks on date getArchs retrieves this parameter. Then getArchs sorts the archives the oldest first. The ordering is actually implemented in the compareTo method of DateArchs. PageBoxListPrincipleThe publisher can display the installation log of an archive on all PageBoxes where the archive has been installed. This is a two-step process: The HTML string returned by the PublishBean’s getArchs method shows archives as links defined like this:
The link points on a PageBoxList servlet that lists the PageBoxes where the archive is installed, populates a ListBean object and forwards the request to a pageboxlist.jsp page. This is another example of MVC design where PageBoxList is the controller, ListBean is the model and pageboxlist.jsp is the view. The HTML string returned by pageboxlist.jsp shows PageBoxes as links defined like this:
The link points on a PageBoxAudit servlet that calls the getAudit method of the PageBox’s DeployIF Web service to get the installation log records of the archive and applies an XSL transformation to display the log. doGetdoGet calls the getSubscribers methods of RepoSubs and RepoASubs to build a map of the subscribers and archive subscribers for the archive given in the arch parameter. Then it instantiates a ListBean object with this map, adds the ListBean object to the request attributes and forwards the request to pageboxlist.jsp. ListBeanpageboxlist.jsp calls the getPageBoxes method of the ListBean object. The getPageBoxes method returns a HTML row per subscriber found in the subscriber map. PageBoxAuditThe doGet method of PageBoxAudit calls the getAudit method of RepoSubs and RepoASubs to get the log records recorded on the PageBox given in parameter for the archive given in parameter. Then doGet applies an XSL transformation to the log stream with the audit-pagebox.xsl stylesheet and returns the transformation result to the user. SubscribeSequence diagramThis sequence diagram shows the subscribe, unsubscribe and force cases.
subscribe.jsp displays a form that displays the PageBoxes already subscribed by the Subscriber. In case of subscribe:
In case of unsubscribe or force:
The difference between unsubscribe and force is that if the undeployment failed the subscribed PageBox state changes to "pending remove" in case of delete whereas the subscribed PageBox is removed in case of force. Class diagram
subscribe.jsp is the view and displays the content of the SubscribeBean model. RepoSubs extends SaveSubs that implements methods also used in RepoASubs such as save. RepoSubs reads subscribers.xml in its init method and rewrites subscribers.xml with the SaveSubs’ save method. RepoSubs updates the SubscribeBean model. Subscribe is the controller. It interprets the user request and invokes RepoSubs. The implementation details are the same as for archive subscriber and described later. Archive subscribeSequence diagramThis sequence diagram shows:
asubscribe.jsp displays a form that displays the PageBoxes already subscribed by the Subscriber. In case of subscribe:
In case of unsubscribe or force:
The difference between unsubscribe and force is that if the undeployment failed the subscribed PageBox state changes to "pending remove" in case of delete whereas the subscribed PageBox is removed in case of force. The subscriber can select a subscribed PageBox to display the list of the archives deployed on this PageBox. The subscriber actually links to aselect.jsp.
Class diagram
There are two view/controller pairs that share the same model:
Views display the SubscribeBean model. Controllers interpret the user request, invoke RepoASubs and update the SubscribeBean model. RepoASubs extends SaveSubs that implements methods also used in RepoSubs such as save. RepoASubs reads asubscribers.xml in its init method and rewrites asubscribers.xml with the SaveSubs’ save method. Subscribe implementationRepoQueryThe RepoQuery Web service implements the following interface:
Where:
url being the URI of the Deploy Web service of a PageBox, code a status code and msg an information message about the archive deployment on this PageBox. code can take a value defined in DeployIF.Status among OK, NOTDEPLOYED, NOTUNDEPLOYED, ARCHPB and PBPB. We describes in the SaveSubs section the use and meaning of these codes.
name being an archive name and status an integer that can take a value defined in DeployIF.Status, OK or ARCHPB. GetSubscribers returns the URIs of the Deploy Web services whose PageBoxes have deployed the archive. Notify is called by PageBox relays to inform the Repository about the status of relayed deployments. NotifyFix is called by PageBox DynDns to inform the Repository about archive status changes triggered by the fix of a PageBox setting problem. RepoQuery implementation class, RepoQueryImpl, implements the RepoQueryIF interface. GetSubscribersThe GetSubscribers method of RepoQueryImpl calls the GetSubscribers method of RepoSubs and RepoASubs to build a map of the Deploy web service of the subscribed PageBox. Then GetSubscribers returns this map converted to an array. NotifyThe Notify method of RepoQueryImpl calls the Notify method of RepoSubs and RepoASub to update the deployment status of the parameter archive on the PageBoxes in the parameter array. NotifyFixThe NotifyFix method of RepoQueryImpl calls the NotifyFix method of RepoSubs and RepoASub to update the deployment status of the archives in the parameter array on the parameter PageBox. RepoSubsIf it doesn’t exist yet, RepoSubs instantiates and initializes a RepoSubs singleton in its public methods, subscribe, unsubscribe, getSubscribers, notify, add, delete and retry, which are static. The initialization takes place in the init method. init creates a SubscribeBean object and restores subscribers.xml in a subscribers member variable of this SubscribeBean object using the SubscriberHandler SAX handler. The subscribers map is saved into subscribers.xml by the save method of SaveSubs. Public static methods except getSubscribers and notify invoke private methods of RepoSubs and SaveSubs:
We describe here the RepoSubs implementation (private method and static methods where a part of the processing takes place). See the SaveSubs section for SaveSubs methods that are shared with RepoASubs. subsub calls the getArchives method of RepoArchs to get the list of the archives defined on the Repository. sub also creates a map of archive status Then for each archive sub:
Eventually sub adds a Subscriber to the SubscribeBean’s subscribers map with the subscriber name (user), the archive status map (archives) and an "active" status. getSubscribersgetSubscribers returns the URLs of the Deploy service of all PageBoxes whose subscriber is the requestor and that have deployed the requested archive. addadd enumerates the subscribed PageBox from the SubscribeBean’s subscribers map. When the subscribed PageBox already has the added archive with an "installed" status add adds the subscribed PageBox to an updatedSubscribers array. Otherwise add adds the subscribed PageBox to an addedSubscribers array. Then add calls the SaveSubs’ addArch method with the addedSubscribers array and the SaveSubs’ updateArch with the updatedSubscribers array. deltaAdddeltaAdd is called by RepoArchs in case of jardiff upload. add enumerates the subscribed PageBox from the SubscribeBean’s subscribers map and adds the subscribed PageBox to an addedSubscribers array. Then deltaAdd calls the SaveSubs’ addArch method with the addedSubscribers array. deletedelete enumerates the subscribed PageBox from the SubscribeBean’s subscribers map. When the subscribed PageBox has the deleted archive delete calls the SaveSubs’ delArch method. syncStarting with version 0.0.9 the archive map status map (archives) of a Subscriber only contains deployed archives. Therefore it may happen that a published archive is not deployed on a subscribed PageBox. Unlike a pending state (the Repository unable to contact the PageBox) this is a permanent condition. There is not point to retry the deployment up to the time the PageBox problem is fixed. Unlike the "PageBox err" state the archive wasn’t transferred therefore once the problem is fixed the archive must be deployed and installed on the subscribed PageBox. For this reason we added a Sync button on the Subscribe form. The sync method is called when the user clicks on the Sync button. sync enumerates the published archives. When an archive is not defined in archives sync
getAuditThe public static getAudit method calls the private getAudit method. The private getAudit method:
RepoASubsIf it doesn’t exist yet, RepoASubs instantiates and initializes a RepoASubs singleton in its public methods, subscribe, unsubscribe, update, getSubscribers, notify, add, delete and retry, which are static. The initialization takes place in the init method. init creates a SubscribeBean object and restores asubscribers.xml in a subscribers member variable of this SubscribeBean instance using the SubscriberHandler SAX handler. The SubscribeBean’s subscribers map is saved into asubscribers.xml by the save method of SaveSubs. Public static methods except getSubscribers invoke private methods of RepoASubs and SaveSubs:
We describe here the RepoASubs implementation (private method and static methods where a part of the processing takes place). See the SaveSubs section for SaveSubs methods that are shared with RepoSubs. subsub adds the subscriber to the SubscribeBean’s subscribers map. updateupdate is called with two main arguments:
update retrieves the subscribed PageBox from the SubscribeBean’s subscribers map using the Deploy Web service URI and from there the map of the archives already deployed on this PageBox. Then update enumerates the archives defined on the Repository using the getArchives method of RepoArchs. If an archive was checked but was not yet deployed on the PageBox, update calls aadd. In an archive was not checked but was deployed on the PageBox, update calls adelete. aaddaadd calls the add method of the Deploy Web service of the target PageBox. Then it adds an entry to the archive status map with the archive name and the status returned by the Deploy invocation if the archive was deployed. adeleteadelete calls the delete method of the Deploy Web service of the target PageBox. Then if the undeployment failed adelete removes the archive entry from the archive status map. Otherwise adelete updates the archive status with the status returned by the Deploy invocation getSubscribersgetSubscribers returns the URLs of the Deploy service of all PageBoxes whose subscriber is the requestor and that have deployed the requested archive. addadd enumerates the subscribed PageBox from the SubscribeBean’s subscribers map. When the subscribed PageBox already has the added archive with an "installed" status add adds the subscribed PageBox to an updatedSubscribers array. Otherwise when the subscribed PageBox already has the added archive add adds the subscribed PageBox to an addedSubscribers array. Then add calls the SaveSubs’ addArch method with the addedSubscribers array and the SaveSubs’ updateArch with the updatedSubscribers array. deltaAdddeltaAdd is called by RepoArchs in case of jardiff upload. add enumerates the subscribed PageBox from the SubscribeBean’s subscribers map and when the subscribed PageBox already has the added archive adds the subscribed PageBox to an addedSubscribers array. Then deltaAdd calls the SaveSubs’ addArch method with the addedSubscribers array. deletedelete enumerates the subscribed PageBox from the SubscribeBean’s subscribers map. When the subscribed PageBox has the deleted archive delete calls the SaveSubs’ delArch method. getAuditThe public static getAudit method calls the private getAudit method. The private getAudit method:
SaveSubsRepoSubs and RepoASubs share the same data format and the same deployment mechanism. Therefore they extend SaveSubs where their common code is implemented. In this section we present:
subscriberssubscribers is a TreeMap whose key is the URI of the Deploy Web service of a subscribed PageBox and value is an Subscriber object:
Where
Starting with version 0.0.9 the deployment (add) and undeployment (delete) methods of the PageBox Web service return a Status object that contains a diagnosis message and a code that unambiguously describes the error. We describe the status object in the Deployer section. We summarize here the mapping of the Status code onto the subscribers map and the Subscriber’s archives map. For the deployment (add) method:
For the undeployment (delete) method:
Therefore the Subscriber’s archive map only contains archives actually deployed. addArchaddArch, updateArch, relay and notify2 are the methods that handle relayed deployment. The mechanism is as follows: If the archive size is above the ceiling value the sender (the Repository or the relay PageBox) divides the archive list in two chunks. The sender sends the first chunk to the first PageBox in the second chunk. Then it repeats the process up to the time there is only one PageBox to deploy. addArch and updateArch prepare the initial chunks and relay recursively issue the actual deployments. notify2 processes the acknowledgements of the relay PageBoxes. addArch processes an archive deployment to an array addedSubscribers of subscribed PageBoxes. If the full archive size is below the ceiling value addArch deploys the archive on all PageBoxes in addedSubscribers and adds the archive and its deployment status to the archive status map of the PageBoxes. If the archive size is greater or equal than the ceiling value addArch calls the relay method with the addedSubscribers array. updateArchupdateArch also processes an archive deployment. The main difference with addArch is that updateArch distributes the archive jardiff. The array of subscribed PageBoxes is called here updatedSubscribers. If the jardiff size is below the ceiling value updateArch deploys the archive on all PageBoxes in updatedSubscribers and updates the deployment status of the archive in the archive status map of the PageBoxes. If the archive size is greater or equal than the ceiling value updateArch calls the relay method with the updatedSubscribers array. relayrelay processes a relayed deployment of an archive to an array subs of subscribed PageBoxes. It first builds an array containing PageBoxes randomly chosen in the subs array:
Then relay deploys on the first PageBox remaining in the subs array and passes the uua array as parameter: this PageBox becomes a relay and is responsible for the deployment on the uua PageBoxes. If this first deployment fails relay retries a deployment on the next subs PageBox and so on. If the deployment fails on all PageBoxes in subs, relay deploys sequentially on the uua PageBoxes. Otherwise relay calls itself passing the subs array. delArchdelArch calls the delete method of the Deploy Web service of the target PageBox to undeploy the archive. If the undeployment is successful delArch removes the archive from the archive status map of the target PageBox. Otherwise delArch updates the status of the archive in the archive status map of the target PageBox to "pending remove" in case of invocation error or if the delete method returned NOTCONTACTED. If the delete method returned NOTUNDEPLOYED delArch unsubscribes the PageBox. unsubunsub is called when a PageBox must be unsubscribed. All archives must be removed before except if it is forced unsubscribe. For each archive deployed on this PageBox unsub
If the unsubscribe was forced or if all PageBox archives were unsubscribed, unsub removes the subscribed PageBox. Otherwise unsub sets the state of the subscribed PageBox to "pending remove". notify2notify2 is called when a relay PageBox calls the Notify method of the RepoQuery Web service. notify2 is called with two main parameters:
For each subscribed PageBox identified by its Deploy service URI in UrlStatus notify2 updates the status of the archive with the value found in UrlStatus. If the archive is in "pending remove" state (delete before the deployment was completed) notify2 calls the delete method of the PageBox DeployIF Web service and updates the status according to the response of the delete call. notifyFix2notifyFix2 is called when a PageBox administrator changed the PageBox setting and retried the installation of archives in "setting pb" state or restarted the PageBox Application server, the change resulting in a state change state to "installed" or "archive err". This change triggers the invocation of the NotifyFix method of the RepoQuery Web service. notifyFix2 is called with two main parameters:
notifyFix2 first retrieves the Subscriber object describing the fixed PageBox. Then for each archive in the FixInfo array notifyFix2 retrieves the ArchiveStatus object describing the archive and updates its status member. retryDeployretryDeploy is called in a worker thread to retry deployments and undeployments and eliminate pending and maybe conditions. For each subscribed PageBox and for each archive deployed in this subscribed PageBox retryDeploy analyzes the archive status. If the status is "pending" or if the status is "maybe" for more than relayTime retryDeploy calls the add method of the Deploy Web service to deploy the archive and updates the archive status according to the Deploy response. If the status is "pending remove" or if the status is "maybe remove" for more than relayTime retryDeploy calls the delete method of the Deploy Web service to undeploy the archive. If the undeployment is successful retryDeploy removes the archive entry from the archive status map. Otherwise it sets the archive status according to the Deploy response. If a subscribed PageBox was in state "pending remove" and if its archive status map is empty retryDeploy removes the subscribed PageBox. SubscribeBeangetSubscribersSubscribeBean implements a static getSubscribers method, which is called by subscribe.jsp. getSubscribers retrieves the RepoSubs instance and then the embedded SubscribeBean instance. Eventually getSubscribers calls the getSubs method of SubscribeBean. getASubscribersSubscribeBean implements a static getASubscribers method, which is called by asubscribe.jsp. getASubscribers retrieves the RepoASubs instance and then the embedded SubscribeBean instance. Eventually getASubscribers calls the getASubs method of SubscribeBean. getArchivesSubscribeBean implements a static getArchives method, which is called by aselect.jsp. getArchives retrieves the RepoASubs instance and then the embedded SubscribeBean instance. Next getArchives determines if the user requested a date sort with getParameter("date"): Two buttons are defined on aselect.jsp to allow sorting by archive name or by publication date. When the user clicks on the date button a date parameter is set. Eventually getArchives calls the getArchs method of SubscribeBean. getSubsgetSubs returns an HTML string that contains a table row per PageBox subscribed on the Repository by the same user as the requestor or by any user when the user is in a pagebox-admin role. These PageBox data are stored in the SubscribeBean’s subscribers map. getASubsgetSubs returns an HTML string that contains a table row per PageBox archive-subscribed on the Repository by the same user as the requestor or by any user when the user is in a pagebox-admin role. These PageBox data are stored in the SubscribeBean’s subscribers map. The difference between getSubs and getASubs is that rows returned by getASubs contain an additional field, which is a link to select.jsp. getArchsgetArchs returns an HTML string that contains a table row per archive published on the Repository. These rows can be sorted either by archive name or by publication date. getArch is called with a subscriber parameter that contains the name of the current subscribed PageBox. getArch uses this name to retrieve the corresponding Subscriber object from the subscribers map. Each row contains a checkbox. getArchs marks this checkbox as checked when the archives map of this Subscriber contains the archive. In case of sort by date getArchs populates a temporary TreeMap tm with the content of archives. The tm key is a DateArch object.
In case of date sort getArchs implements a sort of toggle. The first time the user clicks on date a order boolean is false, which means that archives must be sorted the most recent first. Then getArchs writes a hidden order field in the HTML string. The next time the user clicks on date getArchs retrieves this parameter. Then getArchs sorts the archives the oldest first. The ordering is actually implemented in the compareTo method of DateArchs. DeployerTo call the Deploy Web service subscribe methods uses a Deployer class. Deployer implements a DeployerIF, which is defined like this:
The DeployerIF interface implements the DeployIF interface, which is defined like this:
Where Status is defined like this:
Where code can take an OK, NOTDEPLOYED, NOTRELAYED, ARCHPB, PBPB, NOTUNDEPLOYED or NOTCONTACTED value and msg is a diagnosis message. add deploys an archive, delete undeploys an archive, rename allows changing the download URL (the URI of the RepoQuery Web service) for all archives deployed on a PageBox, getArchPath returns the URL of an installed archive and getAudit returns the log records of a PageBox about an archive installation. Look at the PageBox implementation for more information. Deployer is a facade class that forwards its requests to an actual deployer. A Deployer factory method has a parameter, which is the full class name of the actual deployer. The factory creates the actual deployer and its facade with the following snippet:
The class name of the actual deployer is defined in a deployer-class initialization parameter. This deployer must implement a constructor without parameter and the DeployerIF interface. Three deployers are available:
Starting with PageBox 0.0.11 Deployer, JWSDPDeployer, AxisDeployer and HTTPDeployer support token methods, DeployIF extending the TokenIF interface defined like this:
We describe these methods in the Token API implementation guide. JWSDPDeployerJWSDPDeployer uses the JAX-RPC implementation included in the Java WSDP.
The JWSDPDeployer constructor instantiates a Deploy stub generated with wscompile –gen:client. The setUrl method of JWSDPDeployer sets the URL of the target PageBox Deploy service. For each method of the DeployIF interface JWSDPDeployer calls the corresponding method of the stub. We had a problem with JWSDP 1.2 for the Token API method, frameSend. It seems that this version doesn’t handle properly linked lists (translated in SOAP sequences) of objects. We did not retry with JWSDP 1.3 and JWSDP 1.5. The TokenFrame class used by the frameSend method is defined like this:
Therefore we serialize and unserialize the adjacencyList and msgList entries with the ser and unser methods. AxisDeployerAxisDeployer uses the Axis JAX-RPC implementation. AxisDeployer has a service member variable initialized like this:
DeployServiceLocator is a factory class allowing instantiating the stub class, DeploySoapBindingStub with the Web service URL. DeployServiceLocator, DeploySoapBindingStub and a set of helper classes are generated with org.apache.axis.wsdl.WSDL2Java. The setUrl method of JWSDPDeployer calls the getDeploy method of DeployServiceLocator to instantiate a DeploySoapBindingStub. For each method of the DeployIF interface AxisDeployer calls the corresponding method of the stub. HTTPDeployerHTTPDeployer uses HTTP and calls a HTTPDeploy servlet implemented on target PageBoxes. To the opposite of JWSDPDeployer and AxisDeployer HTTPDeployer doesn’t use JAX-RPC and XML. The setURL method of HTTPDeployer stores:
For each method of the DeployIF interface HTTPDeployer opens a HTTP connection to the target HTTPDeploy servlet, serialize the method parameters and parses the HTTPDeploy servlet response. The first field in the POST request contains a verb that depends on the DeployIF method:
HTTPQueryWhen JAX-RPC is used messages are parsed by a servlet part of the JAX-RPC implementation, JAXRPCServlet in case of JWSDP and AxisServlet in case of Axis. In case of HTTP implementation we must provide this servlet. HTTPQuery has a RepoQueryImpl member instantiated on startup. The init method of HTTPQuery calls the init2 method of the RepoQueryImpl instance. The destroy method of HTTPQuery calls the homonymous method of the RepoQueryImpl instance. HTTPQuery expects POST requests and therefore implements the doPost method. doPost reads the first field of the request, which is the verb and calls a parsing method according to its content:
GetSubscribers unserializes the remaining parameter, calls the homonymous method of the RepoQueryImpl instance, serializes and returns its response. Notify unserializes the remaining parameters and calls the homonymous method of the RepoQueryImpl instance. NotifyFix unserializes the remaining parameters and calls the homonymous method of the RepoQueryImpl instance RetryThe Retry class extends Thread. Its constructor instantiates a DynDns object and starts the worker thread. Its run method (invoked in the worker thread) periodically calls the retry methods of RepoSubs and RepoASubs. These methods call the retryDeploy method of SaveSubs where the core of the retry handling is implemented. The run method also calls the register method of the DynDns object to:
A single Retry object is instantiated in the init method of Subscribe. Therefore the init method of Subscribe must be called when the Repository Web application is loaded (<load-on-startup>0</load-on-startup> in web.xml). DynDnsBackgroundPermanent IP addresses are scarce resources especially in Europe and Asia. The cheapest way to get a permanent IP address is to use the service of an Application Service Provider (ASP). An Internet Service Provider (ISP) buys ranges of IP addresses and allocates these addresses to its customers. Depending on the customer subscription the ISP may allocate a temporary address to a customer. It is usually the case with cable and DSL subscribers and sometimes the case of dial-up subscribers. Users usually don’t know the IP address of a site. Users know the DNS name of the site. A site owner may choose to buy a domain name (about $10 to $20 per year). Buying a domain makes sense for commercial reasons: the site URL is easier to remember and shows a minimal commitment of the provider. For technical sites (syndicated content provider, Web service) a sub-domain name that we usually can get for free is usually enough.
DNS servers handle matching tables:
When the IP address of a host changes (which is likely to happen in case of temporary allocated IP address) it is possible to dynamically update its IP address on the DNS server. PageBoxes, PageBox Repositories and Web applications deployed with PageBox need permanent host names. They don’t require domains and permanent IP addresses. Using temporary IP addresses and sub-domain names actually augments the value of PageBox by enabling server-less constellations:
In this scenario the users host the Application server and the PageBox on their workstation and the publisher hosts an Application server and a Repository on her workstation. Workstations get temporary IP addresses from the users and publisher ISPs. The PageBoxes and the Repository monitor the temporary IP address and update the Dynamic DNS server in case of change.
Using a local Web application instance can be useful for compute-intensive applications (stock trading) or in cases where the user must be able to use the application in disconnected mode (off-line learning). It is obviously also possible to run one Application server and one PageBox per office connected with DSL or WiFi. DNS servers typically support dynamic update with the RFC 2136 protocol. We chose in PageBox version 0.0.8 and above to support the DynDNS HTTP protocol. This protocol is supported by firewalls. Furthermore the DynDNS site offers free sub-domain registration and update. In the future we may implement a DynDNS / RFC 2136 gateway. ImplementationThe DynDNS support is implemented in the DynDns class. This class implements three methods, a constructor, a register and a getHost method. The DynDns constructor first read configuration parameters such as the URL of the registration and update page, authentication parameters, the DNS name to register and either the name of the interface or a local name whose address must be used. If the last configuration parameter is the interface name the constructor retrieves the IP address with NetworkInterface.getByName(inter). If the last configuration parameter is a local name the constructor retrieves the IP address with InetAddress.getByName(name). DynDNS.org policy is to forbid unneeded queries. Therefore DynDns persists the registered domain and address in a dyndns.txt file. This file contains three lines:
The DynDns constructor reads and caches the dyndns.txt file. The register method:
We wrote a small DynDns emulator to test the implementation.
The getHost method returns:
The getHost method is called by the SaveSubs' adjustDownloadURL to build the download URL sent to PageBoxes.
Contact:support@pagebox.net |