KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > invocation > http > servlet > InvokerServlet


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.http.servlet;
23
24 import java.io.IOException JavaDoc;
25 import java.io.ObjectInputStream JavaDoc;
26 import java.io.ObjectOutputStream JavaDoc;
27 import java.lang.reflect.InvocationTargetException JavaDoc;
28 import java.security.PrivilegedAction JavaDoc;
29 import java.security.Principal JavaDoc;
30 import java.security.AccessController JavaDoc;
31 import javax.management.MalformedObjectNameException JavaDoc;
32 import javax.management.MBeanServer JavaDoc;
33 import javax.management.ObjectName JavaDoc;
34 import javax.servlet.ServletConfig JavaDoc;
35 import javax.servlet.ServletException JavaDoc;
36 import javax.servlet.ServletInputStream JavaDoc;
37 import javax.servlet.ServletOutputStream JavaDoc;
38 import javax.servlet.http.HttpServlet JavaDoc;
39 import javax.servlet.http.HttpServletRequest JavaDoc;
40 import javax.servlet.http.HttpServletResponse JavaDoc;
41
42 import org.jboss.invocation.InvocationException;
43 import org.jboss.invocation.MarshalledInvocation;
44 import org.jboss.invocation.MarshalledValue;
45 import org.jboss.logging.Logger;
46 import org.jboss.mx.util.MBeanServerLocator;
47 import org.jboss.mx.util.JMXExceptionDecoder;
48 import org.jboss.system.Registry;
49 import org.jboss.security.SecurityAssociation;
50
51 /** This servlet accepts a post containing a MarshalledInvocation, extracts
52  the Invocation object, and then routes the invocation via JMX to either:
53  1. the MBean specified via the invokerName ini parameter
54  2. the MBean whose object name hash is specified by the invocation.getObjectName()
55  value. This name's hash must have been entered into the Registry.
56
57  The method signature of the invoker must be Object invoke(org.jboss.invocation.Invocation).
58
59  @see org.jboss.system.Registry
60  @see org.jboss.invocation.Invocation
61
62  * @author Scott.Stark@jboss.org
63  * @version $Revision: 37459 $
64  */

65 public class InvokerServlet extends HttpServlet JavaDoc
66 {
67    private static Logger log = Logger.getLogger(InvokerServlet.class);
68    /** A serialized MarshalledInvocation */
69    private static String JavaDoc REQUEST_CONTENT_TYPE =
70       "application/x-java-serialized-object; class=org.jboss.invocation.MarshalledInvocation";
71    /** A serialized MarshalledValue */
72    private static String JavaDoc RESPONSE_CONTENT_TYPE =
73       "application/x-java-serialized-object; class=org.jboss.invocation.MarshalledValue";
74    private MBeanServer JavaDoc mbeanServer;
75    private ObjectName JavaDoc localInvokerName;
76
77    /** Initializes the servlet.
78     */

79    public void init(ServletConfig JavaDoc config) throws ServletException JavaDoc
80    {
81       super.init(config);
82       try
83       {
84          // See if the servlet is bound to a particular invoker
85
String JavaDoc name = config.getInitParameter("invokerName");
86          if( name != null )
87          {
88             localInvokerName = new ObjectName JavaDoc(name);
89             log.debug("localInvokerName="+localInvokerName);
90          }
91       }
92       catch(MalformedObjectNameException JavaDoc e)
93       {
94          throw new ServletException JavaDoc("Failed to build invokerName", e);
95       }
96
97       // Lookup the MBeanServer
98
mbeanServer = MBeanServerLocator.locateJBoss();
99       if( mbeanServer == null )
100          throw new ServletException JavaDoc("Failed to locate the MBeanServer");
101    }
102
103    /** Destroys the servlet.
104     */

105    public void destroy()
106    {
107
108    }
109
110    /** Read a MarshalledInvocation and dispatch it to the target JMX object
111     invoke(Invocation) object.
112
113     @param request servlet request
114     @param response servlet response
115     */

116    protected void processRequest(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
117       throws ServletException JavaDoc, IOException JavaDoc
118    {
119       boolean trace = log.isTraceEnabled();
120       if( trace )
121       {
122          log.trace("processRequest, ContentLength: "+request.getContentLength());
123          log.trace("processRequest, ContentType: "+request.getContentType());
124       }
125
126       Boolean JavaDoc returnValueAsAttribute = (Boolean JavaDoc) request.getAttribute("returnValueAsAttribute");
127       try
128       {
129          response.setContentType(RESPONSE_CONTENT_TYPE);
130          // See if the request already has the MarshalledInvocation
131
MarshalledInvocation mi = (MarshalledInvocation) request.getAttribute("MarshalledInvocation");
132          if( mi == null )
133          {
134             // Get the invocation from the post
135
ServletInputStream JavaDoc sis = request.getInputStream();
136             ObjectInputStream JavaDoc ois = new ObjectInputStream JavaDoc(sis);
137             mi = (MarshalledInvocation) ois.readObject();
138             ois.close();
139          }
140          /* If the invocation carries no auth context, look to to the auth
141          context of this servlet as seen in the SecurityAssocation. This allows
142          the web app authentication to transparently be used as the call
143          authentication.
144          */

145          if (mi.getPrincipal() == null && mi.getCredential() == null)
146          {
147             mi.setPrincipal(GetPrincipalAction.getPrincipal());
148             mi.setCredential(GetCredentialAction.getCredential());
149          }
150          Object JavaDoc[] params = {mi};
151          String JavaDoc[] sig = {"org.jboss.invocation.Invocation"};
152          ObjectName JavaDoc invokerName = localInvokerName;
153          // If there is no associated invoker, get the name from the invocation
154
if( invokerName == null )
155          {
156             Integer JavaDoc nameHash = (Integer JavaDoc) mi.getObjectName();
157             invokerName = (ObjectName JavaDoc) Registry.lookup(nameHash);
158             if( invokerName == null )
159                throw new ServletException JavaDoc("Failed to find invoker name for hash("+nameHash+")");
160          }
161          // Forward the invocation onto the JMX invoker
162
Object JavaDoc value = mbeanServer.invoke(invokerName, "invoke", params, sig);
163          if( returnValueAsAttribute == null || returnValueAsAttribute.booleanValue() == false )
164          {
165             MarshalledValue mv = new MarshalledValue(value);
166             ServletOutputStream JavaDoc sos = response.getOutputStream();
167             ObjectOutputStream JavaDoc oos = new ObjectOutputStream JavaDoc(sos);
168             oos.writeObject(mv);
169             oos.close();
170          }
171          else
172          {
173             request.setAttribute("returnValue", value);
174          }
175       }
176       catch(Throwable JavaDoc t)
177       {
178          t = JMXExceptionDecoder.decode(t);
179          // Unwrap any reflection InvocationTargetExceptions
180
if( t instanceof InvocationTargetException JavaDoc )
181          {
182             InvocationTargetException JavaDoc ite = (InvocationTargetException JavaDoc) t;
183             t = ite.getTargetException();
184          }
185          /* Wrap the exception in an InvocationException to distinguish
186             between application and transport exceptions
187          */

188          InvocationException appException = new InvocationException(t);
189          log.debug("Invoke threw exception", t);
190          // Marshall the exception
191
if( returnValueAsAttribute == null || returnValueAsAttribute.booleanValue() == false )
192          {
193             response.resetBuffer();
194             MarshalledValue mv = new MarshalledValue(appException);
195             ServletOutputStream JavaDoc sos = response.getOutputStream();
196             ObjectOutputStream JavaDoc oos = new ObjectOutputStream JavaDoc(sos);
197             oos.writeObject(mv);
198             oos.close();
199          }
200          else
201          {
202             request.setAttribute("returnValue", appException);
203          }
204       }
205    }
206
207    /** Handles the HTTP <code>GET</code> method.
208     * @param request servlet request
209     * @param response servlet response
210     */

211    protected void doGet(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
212       throws ServletException JavaDoc, IOException JavaDoc
213    {
214       processRequest(request, response);
215    }
216
217    /** Handles the HTTP <code>POST</code> method.
218     * @param request servlet request
219     * @param response servlet response
220     */

221    protected void doPost(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
222       throws ServletException JavaDoc, IOException JavaDoc
223    {
224       processRequest(request, response);
225    }
226
227    /** Returns a short description of the servlet.
228     */

229    public String JavaDoc getServletInfo()
230    {
231       return "An HTTP to JMX invocation servlet";
232    }
233
234    private static class GetPrincipalAction implements PrivilegedAction JavaDoc
235    {
236       static PrivilegedAction JavaDoc ACTION = new GetPrincipalAction();
237       public Object JavaDoc run()
238       {
239          Principal JavaDoc principal = SecurityAssociation.getPrincipal();
240          return principal;
241       }
242       static Principal JavaDoc getPrincipal()
243       {
244          Principal JavaDoc principal = (Principal JavaDoc) AccessController.doPrivileged(ACTION);
245          return principal;
246       }
247    }
248
249    private static class GetCredentialAction implements PrivilegedAction JavaDoc
250    {
251       static PrivilegedAction JavaDoc ACTION = new GetCredentialAction();
252       public Object JavaDoc run()
253       {
254          Object JavaDoc credential = SecurityAssociation.getCredential();
255          return credential;
256       }
257       static Object JavaDoc getCredential()
258       {
259          Object JavaDoc credential = AccessController.doPrivileged(ACTION);
260          return credential;
261       }
262    }
263 }
264
Popular Tags