KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > proxy > ejb > ProxyFactoryHA


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.proxy.ejb;
23
24 import java.util.List JavaDoc;
25 import javax.management.ObjectName JavaDoc;
26 import javax.naming.InitialContext JavaDoc;
27 import org.jboss.system.Registry;
28 import org.jboss.logging.Logger;
29 import org.jboss.invocation.jrmp.interfaces.JRMPInvokerProxyHA;
30 import org.jboss.ha.framework.interfaces.LoadBalancePolicy;
31 import org.jboss.ha.framework.interfaces.DistributedReplicantManager;
32 import org.jboss.ha.framework.interfaces.HAPartition;
33 import org.jboss.ha.framework.server.HATarget;
34
35 import javax.management.AttributeChangeNotificationFilter JavaDoc;
36 import javax.management.NotificationListener JavaDoc;
37 import javax.management.AttributeChangeNotification JavaDoc;
38 import javax.management.Notification JavaDoc;
39 import org.jboss.invocation.InvokerProxyHA;
40 import org.jboss.invocation.InvokerHA;
41 import org.jboss.system.ServiceMBean;
42 import org.jboss.naming.Util;
43
44 /**
45 * ProxyFactory for Clustering
46 *
47 * @author <a HREF="mailto:bill@burkecentral.com">Bill Burke</a>
48 * @version $Revision: 39164 $
49 *
50 * <p><b>Revisions:</b><br>
51 * <p><b>2002/01/13: billb</b>
52 * <ol>
53 * <li>Initial Revisition
54 * </ol>
55 * <p><b>2002/08/24: Sacha Labourey</b>
56 * <ol>
57 * <li>Added a "Proxy Family" string that identifies, for a same HATarget,
58         different families of proxies (remote, home, etc.) that may each
59         have its own client behaviour (round robin, etc.) => each needs its own
60         id in the Proxy Family Repository on the client side</li>
61 * </ol>
62 */

63 public class ProxyFactoryHA
64    extends ProxyFactory
65    implements DistributedReplicantManager.ReplicantListener, ClusterProxyFactory
66 {
67    
68    protected static Logger log = Logger.getLogger(ProxyFactory.class);
69    protected String JavaDoc replicantName = null;
70    protected InvokerHA jrmp;
71    protected HATarget target;
72    
73    protected DistributedReplicantManager drm = null;
74    
75    public void create () throws Exception JavaDoc
76    {
77       super.create ();
78       
79       // we register our inner-class to retrieve STATE notifications from our container
80
//
81
AttributeChangeNotificationFilter JavaDoc filter = new AttributeChangeNotificationFilter JavaDoc ();
82       filter.enableAttribute ("State");
83       
84       // ************************************************************************
85
// NOTE: We could also subscribe for the container service events instead of the
86
// ejbModule service events. This problem comes from beans using other beans
87
// in the same ejbModule: we may receive an IllegalStateException thrown
88
// by the Container implementation. Using ejbModule events solve this
89
// problem.
90
// ************************************************************************
91
this.container.getServer ().
92          addNotificationListener (this.container.getEjbModule ().getServiceName (),
93                                   new ProxyFactoryHA.StateChangeListener (),
94                                   filter,
95                                   null);
96    }
97    
98    public void start () throws Exception JavaDoc
99    {
100       super.start ();
101    }
102    
103    protected void setupInvokers() throws Exception JavaDoc
104    {
105       String JavaDoc partitionName = container.getBeanMetaData().getClusterConfigMetaData().getPartitionName();
106       InitialContext JavaDoc ctx = new InitialContext JavaDoc();
107       HAPartition partition = (HAPartition) ctx.lookup("/HAPartition/" + partitionName);
108       this.drm = partition.getDistributedReplicantManager ();
109       
110       replicantName = jmxName.toString ();
111       
112       ObjectName JavaDoc oname = new ObjectName JavaDoc(invokerMetaData.getInvokerMBean());
113       jrmp = (InvokerHA)Registry.lookup(oname);
114       if (jrmp == null)
115          throw new RuntimeException JavaDoc("home JRMPInvokerHA is null: " + oname);
116
117
118       target = new HATarget(partition, replicantName, jrmp.getStub (), HATarget.MAKE_INVOCATIONS_WAIT);
119       jrmp.registerBean(jmxName, target);
120
121       String JavaDoc clusterFamilyName = partitionName + "/" + jmxName + "/";
122       
123       // make ABSOLUTLY sure we do register with the DRM AFTER the HATarget
124
// otherwise we will refresh the *old* home in JNDI (ie before the proxy
125
// is re-generated)
126
//
127
drm.registerListener (replicantName, this);
128       
129       ClassLoader JavaDoc cl = Thread.currentThread().getContextClassLoader();
130       Class JavaDoc clazz;
131       LoadBalancePolicy policy;
132       
133       clazz = cl.loadClass(container.getBeanMetaData().getClusterConfigMetaData().getHomeLoadBalancePolicy());
134       policy = (LoadBalancePolicy)clazz.newInstance();
135       homeInvoker = jrmp.createProxy(jmxName, policy, clusterFamilyName + "H");
136       // (Re-)Bind the home invoker in the JNDI naming space
137
String JavaDoc homeName = jndiBinding + "-HomeInvoker";
138       log.debug("(re-)Binding Home invoker under: " + homeName);
139       Util.rebind(ctx,
140          // Jndi name
141
homeName,
142          // The home invoker
143
homeInvoker
144       );
145
146       clazz = cl.loadClass(container.getBeanMetaData().getClusterConfigMetaData().getBeanLoadBalancePolicy());
147       policy = (LoadBalancePolicy)clazz.newInstance();
148       beanInvoker = jrmp.createProxy(jmxName, policy, clusterFamilyName + "R");
149       // (Re-)Bind the remote invoker in the JNDI naming space
150
String JavaDoc beanName = jndiBinding + "-RemoteInvoker";
151       log.debug("(re-)Binding Remote invoker under: " + beanName);
152       Util.rebind(ctx,
153          // Jndi name
154
beanName,
155          // The bean invoker
156
beanInvoker
157       );
158
159       JRMPInvokerProxyHA.colocation.add(new Integer JavaDoc(jmxNameHash));
160    }
161    
162    public void destroy ()
163    {
164       super.destroy ();
165       
166       try
167       {
168          JRMPInvokerProxyHA.colocation.remove(new Integer JavaDoc(jmxNameHash));
169          jrmp.unregisterBean(jmxName);
170          target.destroy();
171       }
172       catch (Exception JavaDoc ignored)
173       {
174          // ignore.
175
}
176       try
177       {
178          InitialContext JavaDoc ctx = new InitialContext JavaDoc();
179          String JavaDoc homeInvokerName = jndiBinding + "-HomeInvoker";
180          ctx.unbind(homeInvokerName);
181       }
182       catch(Exception JavaDoc ignored)
183       {
184       }
185       try
186       {
187          InitialContext JavaDoc ctx = new InitialContext JavaDoc();
188          String JavaDoc beanInvokerName = jndiBinding + "-RemoteInvoker";
189          ctx.unbind(beanInvokerName);
190       }
191       catch(Exception JavaDoc ignored)
192       {
193       }
194
195       if( drm != null )
196          drm.unregisterListener (replicantName, this);
197    }
198
199    protected void containerIsFullyStarted ()
200    {
201       if( target != null )
202          target.setInvocationsAuthorization (HATarget.ENABLE_INVOCATIONS);
203    }
204    
205    protected void containerIsAboutToStop ()
206    {
207       if( target != null )
208       {
209          target.setInvocationsAuthorization (HATarget.DISABLE_INVOCATIONS);
210          target.disable ();
211       }
212    }
213
214    // synchronized keyword added when it became possible for DRM to issue
215
// concurrent replicantsChanged notifications. JBAS-2169.
216
public synchronized void replicantsChanged (String JavaDoc key,
217                                                List JavaDoc newReplicants,
218                                                int newReplicantsViewId)
219    {
220       try
221       {
222          if (homeInvoker instanceof InvokerProxyHA)
223          {
224             ((InvokerProxyHA)homeInvoker).updateClusterInfo (target.getReplicants(), target.getCurrentViewId ());
225          }
226          if (beanInvoker instanceof InvokerProxyHA)
227          {
228             ((InvokerProxyHA)beanInvoker).updateClusterInfo (target.getReplicants(), target.getCurrentViewId ());
229          }
230
231          log.debug ("Rebinding in JNDI... " + key);
232          rebindHomeProxy ();
233       }
234       catch (Exception JavaDoc none)
235       {
236          log.debug (none);
237       }
238    }
239
240    // inner-classes
241

242    class StateChangeListener implements NotificationListener JavaDoc
243    {
244       
245       public void handleNotification (Notification JavaDoc notification, java.lang.Object JavaDoc handback)
246       {
247          if (notification instanceof AttributeChangeNotification JavaDoc)
248          {
249             AttributeChangeNotification JavaDoc notif = (AttributeChangeNotification JavaDoc) notification;
250             int value = ((Integer JavaDoc)notif.getNewValue()).intValue ();
251             
252             if (value == ServiceMBean.STARTED)
253             {
254                log.debug ("Container fully started: enabling HA-RMI access to bean");
255                containerIsFullyStarted ();
256             }
257             else if (value == ServiceMBean.STOPPING)
258             {
259                log.debug ("Container about to stop: disabling HA-RMI access to bean");
260                containerIsAboutToStop ();
261             }
262          }
263       }
264       
265    }
266 }
267
Popular Tags