KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > hajdbc > distributable > DistributableDatabaseCluster


1 /*
2  * HA-JDBC: High-Availability JDBC
3  * Copyright (c) 2004-2006 Paul Ferraro
4  *
5  * This library is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU Lesser General Public License as published by the
7  * Free Software Foundation; either version 2.1 of the License, or (at your
8  * option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13  * for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this library; if not, write to the Free Software Foundation,
17  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  * Contact: ferraro@users.sourceforge.net
20  */

21 package net.sf.hajdbc.distributable;
22
23 import java.io.Serializable JavaDoc;
24 import java.util.Collection JavaDoc;
25 import java.util.concurrent.locks.Lock JavaDoc;
26
27 import javax.management.MBeanServer JavaDoc;
28 import javax.management.ObjectName JavaDoc;
29
30 import net.sf.hajdbc.Database;
31 import net.sf.hajdbc.DatabaseClusterFactory;
32 import net.sf.hajdbc.Messages;
33 import net.sf.hajdbc.SQLException;
34 import net.sf.hajdbc.local.LocalDatabaseCluster;
35
36 import org.jgroups.Address;
37 import org.jgroups.Channel;
38 import org.jgroups.JChannel;
39 import org.jgroups.blocks.NotificationBus;
40 import org.jgroups.jmx.JmxConfigurator;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43
44 /**
45  * Decorates an existing database cluster by providing distributable functionality.
46  * Broadcasts database activations and deactivations to other cluster instances on the network.
47  * @author Paul Ferraro
48  * @version $Revision: 1359 $
49  * @since 1.0
50  */

51 public class DistributableDatabaseCluster extends LocalDatabaseCluster implements NotificationBus.Consumer
52 {
53     static Logger logger = LoggerFactory.getLogger(DistributableDatabaseCluster.class);
54     
55     private NotificationBus notificationBus;
56     private DistributableLock lock;
57     private DistributableDatabaseClusterBuilder builder;
58     
59     /**
60      * Constructs a new DistributableDatabaseCluster.
61      * @param builder a builder for this database cluster
62      */

63     public DistributableDatabaseCluster(DistributableDatabaseClusterBuilder builder)
64     {
65         this.builder = builder;
66     }
67     
68     /**
69      * @see net.sf.hajdbc.DatabaseCluster#deactivate(net.sf.hajdbc.Database)
70      */

71     @Override JavaDoc
72     public boolean deactivate(Database database)
73     {
74         boolean deactivated = super.deactivate(database);
75         
76         if (deactivated)
77         {
78             this.notificationBus.sendNotification(new DatabaseDeactivationCommand(database));
79         }
80         
81         return deactivated;
82     }
83
84     /**
85      * @see net.sf.hajdbc.DatabaseCluster#activate(net.sf.hajdbc.Database)
86      */

87     @Override JavaDoc
88     public boolean activate(Database database)
89     {
90         boolean activated = super.activate(database);
91         
92         if (activated)
93         {
94             this.notificationBus.sendNotification(new DatabaseActivationCommand(database));
95         }
96         
97         return activated;
98     }
99
100     /**
101      * @see org.jgroups.blocks.NotificationBus.Consumer#handleNotification(java.io.Serializable)
102      */

103     public void handleNotification(Serializable JavaDoc command)
104     {
105         logger.info(Messages.getMessage(Messages.DATABASE_COMMAND_RECEIVED, command));
106         
107         DatabaseCommand.class.cast(command).execute(this);
108     }
109
110     /**
111      * @see org.jgroups.blocks.NotificationBus.Consumer#getCache()
112      */

113     public Serializable JavaDoc getCache()
114     {
115         Collection JavaDoc<String JavaDoc> databases = super.getActiveDatabases();
116         
117         return databases.toArray(new String JavaDoc[databases.size()]);
118     }
119
120     /**
121      * @see org.jgroups.blocks.NotificationBus.Consumer#memberJoined(org.jgroups.Address)
122      */

123     public void memberJoined(Address address)
124     {
125         String JavaDoc channel = this.notificationBus.getChannel().getChannelName();
126         
127         logger.info(Messages.getMessage(Messages.GROUP_MEMBER_JOINED, address, channel));
128     }
129
130     /**
131      * @see org.jgroups.blocks.NotificationBus.Consumer#memberLeft(org.jgroups.Address)
132      */

133     public void memberLeft(Address address)
134     {
135         String JavaDoc channel = this.notificationBus.getChannel().getChannelName();
136         
137         logger.info(Messages.getMessage(Messages.GROUP_MEMBER_LEFT, address, channel));
138     }
139     
140     /**
141      * @see net.sf.hajdbc.DatabaseCluster#loadState()
142      */

143     @Override JavaDoc
144     public String JavaDoc[] loadState() throws java.sql.SQLException JavaDoc
145     {
146         String JavaDoc[] state = String JavaDoc[].class.cast(this.notificationBus.getCacheFromCoordinator(this.builder.getTimeout(), 1));
147         
148         return (state != null) ? state : super.loadState();
149     }
150     
151     /**
152      * @see net.sf.hajdbc.DatabaseCluster#start()
153      */

154     @Override JavaDoc
155     public synchronized void start() throws java.sql.SQLException JavaDoc
156     {
157         try
158         {
159             this.notificationBus = new NotificationBus(this.getId(), this.builder.getProtocol());
160             this.notificationBus.setConsumer(this);
161             this.notificationBus.start();
162             
163             this.register(this.notificationBus.getChannel());
164             
165             this.lock = new DistributableLock(this.getId() + "-lock", this.builder.getProtocol(), this.builder.getTimeout(), super.writeLock());
166             
167             this.register(this.lock.getChannel());
168
169             super.start();
170         }
171         catch (Exception JavaDoc e)
172         {
173             throw new SQLException(e.toString(), e);
174         }
175     }
176
177     private void register(Channel channel) throws Exception JavaDoc
178     {
179         MBeanServer JavaDoc server = DatabaseClusterFactory.getMBeanServer();
180
181         ObjectName JavaDoc name = this.getObjectName(channel);
182         
183         if (!server.isRegistered(name))
184         {
185             JmxConfigurator.registerChannel(JChannel.class.cast(channel), server, name.getCanonicalName(), true);
186         }
187     }
188     
189     private ObjectName JavaDoc getObjectName(Channel channel) throws Exception JavaDoc
190     {
191         return ObjectName.getInstance("org.jgroups", "channel", ObjectName.quote(channel.getChannelName()));
192     }
193     
194     /**
195      * @see net.sf.hajdbc.DatabaseCluster#stop()
196      */

197     @Override JavaDoc
198     public synchronized void stop()
199     {
200         if (this.notificationBus != null)
201         {
202             this.unregister(this.notificationBus.getChannel());
203             
204             this.notificationBus.stop();
205         }
206
207         if (this.lock != null)
208         {
209             this.unregister(this.lock.getChannel());
210             
211             this.lock.stop();
212         }
213         
214         super.stop();
215     }
216     
217     private void unregister(Channel channel)
218     {
219         MBeanServer JavaDoc server = DatabaseClusterFactory.getMBeanServer();
220         
221         try
222         {
223             ObjectName JavaDoc name = this.getObjectName(channel);
224             
225             if (server.isRegistered(name))
226             {
227                 JmxConfigurator.unregisterChannel(server, name);
228                 JmxConfigurator.unregisterProtocols(server, JChannel.class.cast(channel), name.getCanonicalName());
229             }
230         }
231         catch (Exception JavaDoc e)
232         {
233             logger.warn(e.getMessage(), e);
234         }
235     }
236     
237     /**
238      * @see net.sf.hajdbc.local.LocalDatabaseCluster#writeLock()
239      */

240     @Override JavaDoc
241     public Lock JavaDoc writeLock()
242     {
243         return this.lock;
244     }
245 }
246
Popular Tags