View Javadoc

1   /*
2    * $Id: RmiCallbackMessageReceiver.java 19191 2010-08-25 21:05:23Z tcarlson $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.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.api.MuleEvent;
14  import org.mule.api.MuleException;
15  import org.mule.api.MuleMessage;
16  import org.mule.api.construct.FlowConstruct;
17  import org.mule.api.endpoint.EndpointURI;
18  import org.mule.api.endpoint.InboundEndpoint;
19  import org.mule.api.lifecycle.CreateException;
20  import org.mule.api.transport.Connector;
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, FlowConstruct flowConstruct, InboundEndpoint endpoint)
53              throws CreateException
54      {
55          super(connector, flowConstruct, 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      @Override
78      protected void doDispose()
79      {
80          // template method
81      }
82  
83  
84      /**
85       * Initializes endpoint
86       *
87       * @throws org.mule.transport.ConnectException
88       *
89       */
90      @Override
91      protected void doConnect() throws ConnectException
92      {
93          try
94          {
95              // Do not reinit if RMI is already bound to JNDI!!!
96              // TODO Test how things work under heavy load!!!
97              // Do we need threadlocals or so!?!?
98  
99              // TODO [aperepel] consider AtomicBooleans here
100             // for 'initialised/initialising' status, etc.
101             if (null == remoteObject)
102             {
103                 try
104                 {
105                     InetAddress inetAddress = InetAddress.getByName(endpoint.getEndpointURI().getHost());
106 
107                     bindName = endpoint.getEndpointURI().getPath();
108 
109                     remoteObject = getRmiObject();
110 
111                     Method theMethod = remoteObject.getClass().getMethod("setReceiver",
112                             new Class[]{RmiCallbackMessageReceiver.class});
113                     theMethod.invoke(remoteObject, new Object[]{this});
114 
115                     jndi = connector.getJndiContext(inetAddress.getHostAddress() + ":" + port);
116 
117                     jndi.rebind(bindName, remoteObject);
118                 }
119                 catch (Exception e)
120                 {
121                     throw new ConnectException(e, this);
122                 }
123 
124             }
125         }
126         catch (Exception e)
127         {
128             throw new ConnectException(e, this);
129         }
130     }
131 
132     /** Unbinds Rmi class from registry */
133     @Override
134     protected void doDisconnect()
135     {
136         logger.debug("Disconnecting...");
137 
138         try
139         {
140             jndi.unbind(bindName);
141         }
142         catch (Exception e)
143         {
144             logger.error(e);
145         }
146 
147         logger.debug("Disconnected successfully.");
148     }
149 
150     @Override
151     protected void doStart() throws MuleException
152     {
153         // nothing to do
154     }
155 
156     @Override
157     protected void doStop() throws MuleException
158     {
159         // nothing to do
160     }
161 
162     /**
163      * Gets RmiAble objetc for registry to add in.
164      *
165      * @return java.rmi.Remote and RmiAble implementing class
166      * @throws org.mule.api.lifecycle.ConnectException
167      */
168     private RmiAble getRmiObject() throws ConnectException
169     {
170         String className = (String) endpoint.getProperty(PROPERTY_SERVICE_CLASS_NAME);
171 
172         if (null == className)
173         {
174             throw new ConnectException(RmiMessages.messageReceiverNeedsRmiAble(), this);
175         }
176 
177         RmiAble remote;
178 
179         try
180         {
181             remote = (RmiAble) ClassUtils.instanciateClass(className, new Object[]{}, this.getClass());
182         }
183         catch (Exception e)
184         {
185             throw new ConnectException(RmiMessages.serviceClassInvocationFailed(), e, this);
186         }
187 
188         return (remote);
189     }
190 
191     public MuleEvent routeMessage(Object payload) throws MuleException
192     {
193         MuleMessage messageToRoute = createMuleMessage(payload, endpoint.getEncoding());
194         return routeMessage(messageToRoute);
195     }
196 }