KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > invocation > jrmp > server > JRMPInvokerHA


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.invocation.jrmp.server;
23
24 import java.rmi.MarshalledObject JavaDoc;
25
26 import javax.management.MBeanServer JavaDoc;
27 import javax.management.ObjectName JavaDoc;
28 import javax.management.InstanceNotFoundException JavaDoc;
29 import javax.management.ReflectionException JavaDoc;
30
31 import org.jboss.invocation.jrmp.interfaces.JRMPInvokerProxyHA;
32 import org.jboss.invocation.Invocation;
33 import org.jboss.invocation.Invoker;
34 import org.jboss.invocation.InvokerHA;
35 import org.jboss.invocation.MarshalledInvocation;
36 import org.jboss.system.Registry;
37
38 import org.jboss.ha.framework.interfaces.HARMIResponse;
39 import org.jboss.ha.framework.server.HATarget;
40 import org.jboss.ha.framework.interfaces.LoadBalancePolicy;
41 import org.jboss.ha.framework.interfaces.GenericClusteringException;
42
43 import java.util.ArrayList JavaDoc;
44 import java.util.HashMap JavaDoc;
45
46
47 /**
48  * The JRMPInvokerHA is an HA-RMI implementation that can generate Invocations from RMI/JRMP
49  * into the JMX base
50  *
51  * @author <a HREF="mailto:bill@burkecentral.com>Bill Burke</a>
52  * @author <a HREF="mailto:sacha.labourey@cogito-info.ch">Sacha Labourey</a>.
53  * @author Scott.Stark@jboss.org
54  * @version $Revision: 58564 $
55  */

56 public class JRMPInvokerHA
57    extends JRMPInvoker
58    implements InvokerHA
59 {
60    protected HashMap JavaDoc beanMap = new HashMap JavaDoc();
61    
62    protected ObjectName JavaDoc serviceName;
63    
64    /**
65     * Explicit no-args constructor.
66     */

67    public JRMPInvokerHA()
68    {
69       super();
70    }
71
72    // JRMPInvoker.createService() does the right thing
73

74    protected void startService() throws Exception JavaDoc
75    {
76       loadCustomSocketFactories();
77
78       if (log.isDebugEnabled())
79       {
80          log.debug("RMI Port='" + (rmiPort == ANONYMOUS_PORT ?
81             "Anonymous" : Integer.toString(rmiPort)+"'"));
82          log.debug("Client SocketFactory='" + (clientSocketFactory == null ?
83             "Default" : clientSocketFactory.toString()+"'"));
84          log.debug("Server SocketFactory='" + (serverSocketFactory == null ?
85             "Default" : serverSocketFactory.toString()+"'"));
86          log.debug("Server SocketAddr='" + (serverAddress == null ?
87             "Default" : serverAddress+"'"));
88          log.debug("SecurityDomain='" + (sslDomain == null ?
89             "None" : sslDomain+"'"));
90       }
91
92       exportCI();
93       Registry.bind(getServiceName(), this);
94    }
95
96    protected void stopService() throws Exception JavaDoc
97    {
98       unexportCI();
99    }
100
101    // JRMPInvoker.destroyService() does the right thing
102

103    public void registerBean(ObjectName JavaDoc beanName, HATarget target) throws Exception JavaDoc
104    {
105       Integer JavaDoc hash = new Integer JavaDoc(beanName.hashCode());
106       log.debug("registerBean: "+beanName);
107       
108       if (beanMap.containsKey(hash))
109       {
110          // FIXME [oleg] In theory this is possible!
111
throw new IllegalStateException JavaDoc("Trying to register bean with the existing hashCode");
112       }
113       beanMap.put(hash, target);
114    }
115    
116    public Invoker createProxy(ObjectName JavaDoc beanName, LoadBalancePolicy policy,
117       String JavaDoc proxyFamilyName) throws Exception JavaDoc
118    {
119       Integer JavaDoc hash = new Integer JavaDoc(beanName.hashCode());
120       HATarget target = (HATarget) beanMap.get(hash);
121       if (target == null)
122       {
123          throw new IllegalStateException JavaDoc("The bean hashCode not found");
124       }
125
126       String JavaDoc familyName = proxyFamilyName;
127       if (familyName == null)
128          familyName= target.getAssociatedPartition().getPartitionName() + "/" + beanName;
129
130       JRMPInvokerProxyHA proxy = new JRMPInvokerProxyHA(target.getReplicants(),
131                                                         policy,
132                                                         familyName,
133                                                         target.getCurrentViewId ());
134       return proxy;
135    }
136
137    public void unregisterBean(ObjectName JavaDoc beanName) throws Exception JavaDoc
138    {
139       Integer JavaDoc hash = new Integer JavaDoc(beanName.hashCode());
140       beanMap.remove(hash);
141    }
142
143    /**
144     * Invoke a Remote interface method.
145     */

146    public Object JavaDoc invoke(Invocation invocation)
147       throws Exception JavaDoc
148    {
149       ClassLoader JavaDoc oldCl = Thread.currentThread().getContextClassLoader();
150
151       try
152       {
153          // Deserialize the transaction if it is there
154
invocation.setTransaction(importTPC(((MarshalledInvocation) invocation).getTransactionPropagationContext()));
155
156          // Extract the ObjectName, the rest is still marshalled
157
ObjectName JavaDoc mbean = (ObjectName JavaDoc) Registry.lookup(invocation.getObjectName());
158          long clientViewId = ((Long JavaDoc)invocation.getValue("CLUSTER_VIEW_ID")).longValue();
159
160          HATarget target = (HATarget)beanMap.get(invocation.getObjectName());
161          if (target == null)
162          {
163             // We could throw IllegalStateException but we have a race condition that could occur:
164
// when we undeploy a bean, the cluster takes some time to converge
165
// and to recalculate a new viewId and list of replicant for each HATarget.
166
// Consequently, a client could own an up-to-date list of the replicants
167
// (before the cluster has converged) and try to perform an invocation
168
// on this node where the HATarget no more exist, thus receiving a
169
// wrong exception and no failover is performed with an IllegalStateException
170
//
171
throw new GenericClusteringException(GenericClusteringException.COMPLETED_NO,
172                                                  "target is not/no more registered on this node");
173          }
174          
175          if (!target.invocationsAllowed ())
176             throw new GenericClusteringException(GenericClusteringException.COMPLETED_NO,
177                                         "invocations are currently not allowed on this target");
178
179          // The cl on the thread should be set in another interceptor
180
Object JavaDoc rtn = support.getServer().invoke(mbean,
181                                                  "invoke",
182                                                  new Object JavaDoc[] { invocation },
183                                                  Invocation.INVOKE_SIGNATURE);
184          
185          HARMIResponse rsp = new HARMIResponse();
186
187          if (clientViewId != target.getCurrentViewId())
188          {
189             rsp.newReplicants = new ArrayList JavaDoc(target.getReplicants());
190             rsp.currentViewId = target.getCurrentViewId();
191          }
192          rsp.response = rtn;
193          
194          return new MarshalledObject JavaDoc(rsp);
195       }
196       catch (InstanceNotFoundException JavaDoc e)
197       {
198          throw new GenericClusteringException(GenericClusteringException.COMPLETED_NO, e);
199       }
200       catch (ReflectionException JavaDoc e)
201       {
202          throw new GenericClusteringException(GenericClusteringException.COMPLETED_NO, e);
203       }
204       catch (Exception JavaDoc e)
205       {
206          org.jboss.mx.util.JMXExceptionDecoder.rethrow(e);
207
208          // the compiler does not know an exception is thrown by the above
209
throw new org.jboss.util.UnreachableStatementException();
210       }
211       finally
212       {
213          Thread.currentThread().setContextClassLoader(oldCl);
214       }
215    }
216    
217    public ObjectName JavaDoc getServiceName()
218    {
219       return (serviceName == null ? support.getServiceName() : serviceName);
220    }
221    
222    public void setServiceName(ObjectName JavaDoc serviceName)
223    {
224       this.serviceName = serviceName;
225    }
226
227    @Override JavaDoc
228    public ObjectName JavaDoc preRegister(MBeanServer JavaDoc server, ObjectName JavaDoc name) throws Exception JavaDoc
229    {
230       ObjectName JavaDoc result = super.preRegister(server, name);
231       
232       if (!result.equals(getServiceName()))
233          throw new IllegalStateException JavaDoc("JMX registration (" + result +
234                ") differs from our configured service name (" +
235                getServiceName() +")");
236       
237       return result;
238    }
239    
240    
241    
242    
243 }
244
245
Popular Tags