This section completes this chapter by upgrading a cluster with the new class. The class being upgraded is the Person class discussed in the section called “Upgrade utility”. The simple application show in Example 8.4, “Upgrade application” is being deployed. This application performs these steps:
Define and enable a partition.
Create a Person
object.
Wait for the operator to shut down the application.
Example 8.4. Upgrade application
// $Revision: 1.1.2.2 $ package com.kabira.snippets.upgrade; import com.kabira.platform.highavailability.ReplicaNode; import static com.kabira.platform.highavailability.ReplicaNode.ReplicationType.*; import com.kabira.platform.Transaction; import com.kabira.platform.Transaction.Rollback; import com.kabira.platform.highavailability.PartitionMapper; import com.kabira.platform.highavailability.PartitionManager; import static com.kabira.platform.highavailability.PartitionManager.EnableAction.*; // // Partition mapper that puts all objects in a known partition // class Mapper extends PartitionMapper { final static String PARTITION_NAME = "Upgrade"; @Override public String getPartition(Object obj) { return PARTITION_NAME; } } /** * Define a partition and create an instance of an object that will be upgraded * * <p> * <h2> Target Nodes</h2> * <ul> * <li> <b>domainnode</b> = "A" * </ul> */ public class Upgrade { /** * Main entry point * * @param args Not used * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { new Transaction("Upgrade") { @Override protected void run() throws Rollback { PartitionManager.setMapper(Person.class, new Mapper()); ReplicaNode [] replicas = new ReplicaNode [] { new ReplicaNode("B", SYNCHRONOUS), new ReplicaNode("C", SYNCHRONOUS) }; PartitionManager.definePartition( Mapper.PARTITION_NAME, null, "A", replicas); PartitionManager.enablePartitions(JOIN_CLUSTER); } }.execute(); new Transaction("Create Object") { @Override protected void run() throws Rollback { new Person(); } }.execute(); waitForStop(); } // // Wait for termination // private static void waitForStop() throws InterruptedException { System.out.println("Waiting for stop..."); while (true) { Thread.sleep(5000); } } }
The application is deployed by copying the JAR file containing the
upgrade application to a deployment directory and using the deployment
tool in detached mode to deploy the application. These steps are shown for
a deployment directory located in
/Volumes/kabira/ast/deploy
.
# # Copy JAR file to deployment directory. # The snippet.jar file is used which is the output of building # the entire snippets project. # cp snippets.jar /Volumes/kabira/ast/deploy # # Deploy the application to node A using the deployment tool. # # NOTE: hostname will be specific to your environment. # java -jar deploy.jar detach=true username=guest password=guest \ hostname=172.16.208.128 adminport=2000 domainnode=A \ com.kabira.snippets.upgrade.Upgrade INFO: deploy.jar version: [TIBCO TIBCO BusinessEvents® Extreme 2.2.0 (build 120302)] starting at [Sat Mar 10 09:10:41 PST 2012] INFO: node [A] version: [TIBCO TIBCO BusinessEvents® Extreme 2.2.0 (build 120302)] INFO: node [A] JVM remote debugger agent listening on port [21267] ... INFO: Starting application [com.kabira.snippets.upgrade.Upgrade] ... [A] WARNING: loopback ip address choosen, this agent may not connect to remote agents [A] ip_address=127.0.0.1 port=50004 [A] Listening for transport dt_socket at address: 21267 [A] INFO: JMX Management Service started at: [A] kabira-server:2099 [A] 172.16.208.130:2099 [A] service:jmx:rmi:///jndi/rmi://kabira-server:2099/jmxrmi [A] Waiting for stop... INFO: Component [com.kabira.snippets.upgrade.Upgrade] started in detached mode.
Displaying the initial version of a Person
object
in shared memory on node A
shows the values in Figure 8.2, “Initial version of person object”.
The replicated version of this object has the same values on replica
nodes B
and C
.
The Person
class is updated and a new version of
the snippets.jar
file is generated and deployed into
the deployment directory after generating an upgrade
plan as shown in the section called “Upgrade utility”. Node
A is then upgraded using the TIBCO BusinessEvents® Extreme
Administrator Upgrade
or Restore...
node dialog shown in Figure 8.3, “Upgrade node”.
When the upgrade completes an upgrade report is displayed as shown below.
[A] Starting upgrade ... [A] [A] Removing node A from the cluster ... [A] [A] Stopping node A ... [A] [A] Stopping node [A] node::administration stopping ... [A] Ok [A] distribution::distribution stopping ... Ok [A] application::com_kabira_snippets_upgrade_Upgrade1 stopping ... Ok [A] Node stopped [A] [A] Starting type replacement on node A ... [A] running [A] running [A] running [A] complete [A] [A] Starting node A ... [A] [A] Node A is already running. [A] [A] Node A is configured to use DEVELOPMENT executables [A] Node A shared memory size is 512Mb [A] Node A path: /opt/kabira/run/ast/nodes/A [A] Node A host: kabira-server [A] [A] System Coordinator Host: All Interfaces [A] System Coordinator Port: 2001 [A] [A] Web Server Host: All Interfaces [A] Web Server Port: 12796 [A] [A] Waiting for application to start ...... [A] [A] Components started [A] Loading configurations [A] Auditing security configuration [A] Host: localhost [A] Administration Port: 2001 [A] Service Name: "A" [A] Node Name: "A" [A] [A] Updating partitions on node A ... [A] Partition Name = Upgrade [A] Active Node = B [A] Replica Nodes = C,A [A] [A] Enabling partitions on node A ... [A] ... [A] ... [A] ... [A] ... [A] ... [A] Partition Name = Upgrade [A] Partition State = Active [A] Last State Change Time = 2011-10-07 13:29:08 [A] Active Node = B [A] Replica Nodes = C:synchronous,A:synchronous [A] [A] Completed upgrade. [A] [A] Summary: [A] Node: A [A] Node state when command started: Running [A] Action: upgrade [A] Execute: true [A] Started: Fri Oct 7 13:28:40 PDT 2011 [A] Finished: Fri Oct 7 13:29:09 PDT 2011 [A] Classes File: /var/tmp/kmphpCpuNvx/upgrade.111007 [A] Original Deployment Directories: /opt/kabira/run/ast/deploy [A] New Deployment Directories: /opt/kabira/run/ast/deploy [A] [A] Classes upgraded: [A] Class name: com.kabira.snippets.upgrade.Person [A] Current version: Not Set [A] New version: 1 [A] [A] Active partitions migrated during upgrade: [A] Partition Name: Upgrade [A] Number of Objects: 1 [A] New Active Node: B
At this point there are two different versions of the
Person
class deployed in the cluster. This can be seen
in Figure 8.4, “Cluster version mismatch”. Notice that node
A
is reporting a local version of 1 and no remote
version, while node B
and C
are
reporting no local version, but a remote version of 1 for node
A
. This is because the new class deployed on node
A
defined a serialVersionUID
field
with a value of 1, while the old class version did not define a
serialVersionUID
field.
The object mapping can be seen by displaying the same object
instance on two different nodes. Figure 8.5, “Initial version - node B” shows the initial version of the
Person
object on replica node B
.
Notice that it only has two fields - name
and
age
.
Compare the display of the same object on node A
,
which has been upgraded to the new class version. There was a new field,
type
, added by the new parent class which was
initialized to a value of Human
. The
name
field was also broke into two fields -
first
and last
. Finally, the type of
the age
field was changed. It is important to emphasis
that the different application versions on the two different nodes see the
exact same object differently. The mapping is completely
transparent.