View Javadoc

1   /*
2    * $Id: RmiCallbackMessageReceiver.java 10961 2008-02-22 19:01:02Z dfeist $
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.transport.rmi;
12  
13  import org.mule.DefaultMuleMessage;
14  import org.mule.api.MuleException;
15  import org.mule.api.endpoint.EndpointURI;
16  import org.mule.api.endpoint.InboundEndpoint;
17  import org.mule.api.lifecycle.CreateException;
18  import org.mule.api.service.Service;
19  import org.mule.api.transport.Connector;
20  import org.mule.api.transport.MessageAdapter;
21  import org.mule.transport.AbstractMessageReceiver;
22  import org.mule.transport.ConnectException;
23  import org.mule.transport.rmi.i18n.RmiMessages;
24  import org.mule.util.ClassUtils;
25  
26  import java.lang.reflect.Method;
27  import java.net.InetAddress;
28  
29  import javax.naming.Context;
30  
31  /** TODO */
32  
33  public class RmiCallbackMessageReceiver extends AbstractMessageReceiver
34  {
35      /**
36       * The property name for the service object implementing the callback interface
37       * RmiAble This should be set on the inbound endpoint
38       */
39      public static final String PROPERTY_SERVICE_CLASS_NAME = "serviceClassName";
40  
41      protected RmiConnector connector;
42  
43      protected RmiAble remoteObject = null;
44  
45      private Context jndi = null;
46  
47      private String bindName = null;
48  
49      private int port;
50  
51  
52      public RmiCallbackMessageReceiver(Connector connector, Service service, InboundEndpoint endpoint)
53              throws CreateException
54      {
55          super(connector, service, endpoint);
56          this.connector = (RmiConnector) connector;
57  
58          logger.debug("Initializing with endpoint " + endpoint);
59  
60          String rmiPolicyPath = this.connector.getSecurityPolicy();
61  
62          System.setProperty("java.security.policy", rmiPolicyPath);
63  
64          EndpointURI endpointUri = endpoint.getEndpointURI();
65  
66          port = endpointUri.getPort();
67  
68          if (port < 1)
69          {
70              port = RmiConnector.DEFAULT_RMI_muleRegistry_PORT;
71          }
72  
73  
74          logger.debug("Initialized successfully");
75      }
76  
77      protected void doDispose()
78      {
79          // template method
80      }
81  
82  
83      /**
84       * Initializes endpoint
85       *
86       * @throws org.mule.transport.ConnectException
87       *
88       */
89      protected void doConnect() throws ConnectException
90      {
91          try
92          {
93              // Do not reinit if RMI is already bound to JNDI!!!
94              // TODO Test how things work under heavy load!!!
95              // Do we need threadlocals or so!?!?
96  
97              // TODO [aperepel] consider AtomicBooleans here
98              // for 'initialised/initialising' status, etc.
99              if (null == remoteObject)
100             {
101                 try
102                 {
103                     InetAddress inetAddress = InetAddress.getByName(endpoint.getEndpointURI().getHost());
104 
105                     bindName = endpoint.getEndpointURI().getPath();
106 
107                     remoteObject = getRmiObject();
108 
109                     Method theMethod = remoteObject.getClass().getMethod("setReceiver",
110                             new Class[]{RmiCallbackMessageReceiver.class});
111                     theMethod.invoke(remoteObject, new Object[]{this});
112 
113                     jndi = connector.getJndiContext(inetAddress.getHostAddress() + ":" + port);
114 
115                     jndi.rebind(bindName, remoteObject);
116                 }
117                 catch (Exception e)
118                 {
119                     throw new ConnectException(e, this);
120                 }
121 
122             }
123         }
124         catch (Exception e)
125         {
126             throw new ConnectException(e, this);
127         }
128     }
129 
130     /** Unbinds Rmi class from registry */
131     protected void doDisconnect()
132     {
133         logger.debug("Disconnecting...");
134 
135         try
136         {
137             jndi.unbind(bindName);
138         }
139         catch (Exception e)
140         {
141             logger.error(e);
142         }
143 
144         logger.debug("Disconnected successfully.");
145     }
146 
147     protected void doStart() throws MuleException
148     {
149         // nothing to do
150     }
151 
152     protected void doStop() throws MuleException
153     {
154         // nothing to do
155     }
156 
157     /**
158      * Gets RmiAble objetc for registry to add in.
159      *
160      * @return java.rmi.Remote and RmiAble implementing class
161      * @throws org.mule.api.lifecycle.ConnectException
162      *
163      */
164     private RmiAble getRmiObject() throws ConnectException
165     {
166         String className = (String) endpoint.getProperty(PROPERTY_SERVICE_CLASS_NAME);
167 
168         if (null == className)
169         {
170             throw new ConnectException(RmiMessages.messageReceiverNeedsRmiAble(), this);
171         }
172 
173         RmiAble remote;
174 
175         try
176         {
177             remote = (RmiAble) ClassUtils.instanciateClass(className, new Object[]{}, this.getClass());
178         }
179         catch (Exception e)
180         {
181             throw new ConnectException(RmiMessages.serviceClassInvocationFailed(), e, this);
182         }
183 
184         return (remote);
185     }
186 
187     /**
188      * Routes message forward
189      *
190      * @param message
191      * @return
192      * @throws org.mule.api.MuleException
193      */
194     public Object routeMessage(Object message) throws MuleException
195     {
196         MessageAdapter adapter = connector.getMessageAdapter(message);
197 
198         return (routeMessage(new DefaultMuleMessage(adapter)));
199     }
200 }