View Javadoc

1   /*
2    * $Id: RmiCallbackMessageReceiver.java 7976 2007-08-21 14:26:13Z dirk.olmes $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.providers.rmi;
12  
13  import org.mule.impl.MuleMessage;
14  import org.mule.providers.AbstractMessageReceiver;
15  import org.mule.providers.ConnectException;
16  import org.mule.providers.rmi.i18n.RmiMessages;
17  import org.mule.umo.MessagingException;
18  import org.mule.umo.UMOComponent;
19  import org.mule.umo.UMOException;
20  import org.mule.umo.endpoint.UMOEndpoint;
21  import org.mule.umo.endpoint.UMOEndpointURI;
22  import org.mule.umo.lifecycle.InitialisationException;
23  import org.mule.umo.provider.UMOConnector;
24  import org.mule.umo.provider.UMOMessageAdapter;
25  import org.mule.util.ClassUtils;
26  
27  import java.lang.reflect.Method;
28  import java.net.InetAddress;
29  
30  import javax.naming.Context;
31  
32  /**
33   * TODO
34   */
35  
36  public class RmiCallbackMessageReceiver extends AbstractMessageReceiver
37  {
38      /**
39       * The property name for the service object implementing the callback interface
40       * RmiAble This should be set on the inbound endpoint
41       */
42      public static final String PROPERTY_SERVICE_CLASS_NAME = "serviceClassName";
43  
44      protected RmiConnector connector;
45  
46      protected RmiAble remoteObject = null;
47  
48      private Context jndi = null;
49  
50      private String bindName = null;
51  
52      public RmiCallbackMessageReceiver(UMOConnector connector, UMOComponent component, UMOEndpoint endpoint)
53          throws InitialisationException
54      {
55          super(connector, component, endpoint);
56          this.connector = (RmiConnector)connector;
57      }
58  
59      protected void doDispose()
60      {
61          // template method
62      }
63  
64      /**
65       * Actual initialization. Attempts to rebind service object to Jndi Tree for
66       * discovery
67       * 
68       * @param endpoint
69       * @throws org.mule.umo.lifecycle.InitialisationException
70       */
71      private void initialize(UMOEndpoint endpoint) throws InitialisationException
72      {
73          logger.debug("Initializing with endpoint " + endpoint);
74  
75          String rmiPolicyPath = connector.getSecurityPolicy();
76  
77          System.setProperty("java.security.policy", rmiPolicyPath);
78  
79          UMOEndpointURI endpointUri = endpoint.getEndpointURI();
80  
81          int port = endpointUri.getPort();
82  
83          if (port < 1)
84          {
85              port = RmiConnector.DEFAULT_RMI_REGISTRY_PORT;
86          }
87  
88          try
89          {
90              InetAddress inetAddress = InetAddress.getByName(endpointUri.getHost());
91  
92              bindName = endpointUri.getPath();
93  
94              remoteObject = getRmiObject();
95  
96              Method theMethod = remoteObject.getClass().getMethod("setReceiver",
97                  new Class[]{RmiCallbackMessageReceiver.class});
98              theMethod.invoke(remoteObject, new Object[]{this});
99  
100             jndi = connector.getJndiContext(inetAddress.getHostAddress() + ":" + port);
101 
102             jndi.rebind(bindName, remoteObject);
103         }
104         catch (Exception e)
105         {
106             throw new InitialisationException(e, this);
107         }
108 
109         logger.debug("Initialized successfully");
110     }
111 
112     /**
113      * Initializes endpoint
114      * 
115      * @throws org.mule.providers.ConnectException
116      */
117     protected void doConnect() throws ConnectException
118     {
119         try
120         {
121             // Do not reinit if RMI is already bound to JNDI!!!
122             // TODO Test how things work under heavy load!!!
123             // Do we need threadlocals or so!?!?
124 
125             // TODO [aperepel] consider AtomicBooleans here
126             // for 'initialised/initialising' status, etc.
127             if (null == remoteObject)
128             {
129                 initialize(getEndpoint());
130             }
131         }
132         catch (Exception e)
133         {
134             throw new ConnectException(e, this);
135         }
136     }
137 
138     /**
139      * Unbinds Rmi class from registry
140      */
141     protected void doDisconnect()
142     {
143         logger.debug("Disconnecting...");
144 
145         try
146         {
147             jndi.unbind(bindName);
148         }
149         catch (Exception e)
150         {
151             logger.error(e);
152         }
153 
154         logger.debug("Disconnected successfully.");
155     }
156 
157     protected void doStart() throws UMOException
158     {
159         // nothing to do
160     }
161 
162     protected void doStop() throws UMOException
163     {
164         // nothing to do
165     }
166 
167     /**
168      * Gets RmiAble objetc for registry to add in.
169      * 
170      * @return java.rmi.Remote and RmiAble implementing class
171      * @throws org.mule.umo.lifecycle.InitialisationException
172      */
173     private RmiAble getRmiObject() throws InitialisationException
174     {
175         String className = (String)endpoint.getProperty(PROPERTY_SERVICE_CLASS_NAME);
176 
177         if (null == className)
178         {
179             throw new InitialisationException(RmiMessages.messageReceiverNeedsRmiAble(), this);
180         }
181 
182         RmiAble remote = null;
183 
184         try
185         {
186             remote = (RmiAble)ClassUtils.instanciateClass(className, new Object[] { }, this.getClass());
187         }
188         catch (Exception e)
189         {
190             throw new InitialisationException(RmiMessages.serviceClassInvocationFailed(), e);
191         }
192 
193         return (remote);
194     }
195 
196     /**
197      * Routes message forward
198      * 
199      * @param message
200      * @return
201      * @throws org.mule.umo.MessagingException
202      * @throws org.mule.umo.UMOException
203      */
204     public Object routeMessage(Object message) throws MessagingException, UMOException
205     {
206         UMOMessageAdapter adapter = connector.getMessageAdapter(message);
207 
208         return (routeMessage(new MuleMessage(adapter)));
209     }
210 }