Hello Everyone / Mr Scott , I have been able to churn out a patch finally.
The request level dispatcher is being stored in a member variable of a class derived from XmlRpcHttpRequestConfigImpl . in the execute method of ServiceRpcHandler the dispatcher is being extracted from the config. This has been tested in a simulated concurrent scenario that was previously failing to provide correct results unless dispatcher was localized at request level. Kindly have a look at the attached patch. regds mallah On Tue, Aug 7, 2018 at 11:08 AM, Rajesh Mallah <mallah.raj...@gmail.com> wrote: > > Hi , > > I was giving this problem another shot but need help. > > > The original problem is that , it is not possible to direct > XML / RPC requests to specific tenants in a multi-tenant > environment. This problem is significant as it forces us to have > multiple instances of ofbiz running which are not utilized to fullest > extent. > > > The exact problem i am facing is that i need to get 'HttpServletRequest' > object inside the handler that implements XmlRpcHandler. This is to > create "local" copies of dispatcher and delegator on per - request basis > as Scott suggested not to use the class level variables of the singleton > due to concurrency concerns. > > pls refer: framework/webapp/src/main/java/org/apache/ofbiz/webapp/ > event/XmlRpcEventHandler.java > > if we are able to get HttpServletRequest inside the handler > we could get the delegator and dispatcher as: > > ===================== > dispatcher = (LocalDispatcher) request.getAttribute("dispatcher"); > delegator = (Delegator) request.getAttribute("delegator"); > > ===================== > > A JIRA for the same was already filed: > > >> https://issues.apache.org/jira/browse/OFBIZ-10284 > > Someone else had also faced a similar situation here: > > https://coderanch.com/t/415677/java/remote-IP-Address-JAX-RPC > > > Any suggestions is humbly solicited. > > regds > mallah. > > > > > >
diff --git a/webapp/src/main/java/org/apache/ofbiz/webapp/event/XmlRpcEventHandler.java b/webapp/src/main/java/org/apache/ofbiz/webapp/event/XmlRpcEventHandler.java index 11bf706..e39188e 100644 --- a/webapp/src/main/java/org/apache/ofbiz/webapp/event/XmlRpcEventHandler.java +++ b/webapp/src/main/java/org/apache/ofbiz/webapp/event/XmlRpcEventHandler.java @@ -59,42 +59,42 @@ import org.apache.ofbiz.service.ServiceUtil; import org.apache.ofbiz.webapp.control.ConfigXMLReader; import org.apache.ofbiz.webapp.control.ConfigXMLReader.Event; import org.apache.ofbiz.webapp.control.ConfigXMLReader.RequestMap; /** * XmlRpcEventHandler */ public class XmlRpcEventHandler extends XmlRpcHttpServer implements EventHandler { public static final String module = XmlRpcEventHandler.class.getName(); - protected Delegator delegator; protected LocalDispatcher dispatcher; private Boolean enabledForExtensions = null; private Boolean enabledForExceptions = null; public void init(ServletContext context) throws EventHandlerException { String delegatorName = context.getInitParameter("entityDelegatorName"); - this.delegator = DelegatorFactory.getDelegator(delegatorName); + Delegator delegator = DelegatorFactory.getDelegator(delegatorName); this.dispatcher = ServiceContainer.getLocalDispatcher(delegator.getDelegatorName(), delegator); this.setHandlerMapping(new ServiceRpcHandler()); String extensionsEnabledString = context.getInitParameter("xmlrpc.enabledForExtensions"); if (UtilValidate.isNotEmpty(extensionsEnabledString)) { enabledForExtensions = Boolean.valueOf(extensionsEnabledString); } String exceptionsEnabledString = context.getInitParameter("xmlrpc.enabledForExceptions"); if (UtilValidate.isNotEmpty(exceptionsEnabledString)) { enabledForExceptions = Boolean.valueOf(exceptionsEnabledString); } } + /** * @see org.apache.ofbiz.webapp.event.EventHandler#invoke(ConfigXMLReader.Event, ConfigXMLReader.RequestMap, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ public String invoke(Event event, RequestMap requestMap, HttpServletRequest request, HttpServletResponse response) throws EventHandlerException { String report = request.getParameter("echo"); if (report != null) { BufferedReader reader = null; StringBuilder buf = new StringBuilder(); try { // read the inputstream buffer @@ -143,21 +143,21 @@ public class XmlRpcEventHandler extends XmlRpcHttpServer implements EventHandler return null; } @Override protected void setResponseHeader(ServerStreamConnection con, String header, String value) { ((HttpStreamConnection) con).getResponse().setHeader(header, value); } protected XmlRpcHttpRequestConfig getXmlRpcConfig(HttpServletRequest req) { - XmlRpcHttpRequestConfigImpl result = new XmlRpcHttpRequestConfigImpl(); + OFBizXmlRpcHttpRequestConfigImpl result = new OFBizXmlRpcHttpRequestConfigImpl(req); XmlRpcHttpServerConfig serverConfig = (XmlRpcHttpServerConfig) getConfig(); result.setBasicEncoding(serverConfig.getBasicEncoding()); result.setContentLengthOptional(serverConfig.isContentLengthOptional()); result.setEnabledForExtensions(serverConfig.isEnabledForExtensions()); result.setGzipCompressing(HttpUtil.isUsingGzipEncoding(req.getHeader("Content-Encoding"))); result.setGzipRequesting(HttpUtil.isUsingGzipEncoding(req.getHeaders("Accept-Encoding"))); result.setEncoding(req.getCharacterEncoding()); //result.setEnabledForExceptions(serverConfig.isEnabledForExceptions()); HttpUtil.parseAuthorization(result, req.getHeader("Authorization")); @@ -168,21 +168,22 @@ public class XmlRpcEventHandler extends XmlRpcHttpServer implements EventHandler } if (enabledForExceptions != null) { result.setEnabledForExtensions(enabledForExceptions); } return result; } class OfbizRpcAuthHandler implements AbstractReflectiveHandlerMapping.AuthenticationHandler { public boolean isAuthorized(XmlRpcRequest xmlRpcReq) throws XmlRpcException { - XmlRpcHttpRequestConfig config = (XmlRpcHttpRequestConfig) xmlRpcReq.getConfig(); + OFBizXmlRpcHttpRequestConfigImpl config = (OFBizXmlRpcHttpRequestConfigImpl) xmlRpcReq.getConfig(); + LocalDispatcher dispatcher = config.getDispatcher(); ModelService model; try { model = dispatcher.getDispatchContext().getModelService(xmlRpcReq.getMethodName()); } catch (GenericServiceException e) { throw new XmlRpcException(e.getMessage(), e); } if (model != null && model.auth) { String username = config.getBasicUserName(); @@ -223,20 +224,24 @@ public class XmlRpcEventHandler extends XmlRpcHttpServer implements EventHandler } catch (GenericServiceException e) { Debug.logWarning(e, module); } if (model == null) { throw new XmlRpcNoSuchHandlerException("No such service [" + method + "]"); } return this; } public Object execute(XmlRpcRequest xmlRpcReq) throws XmlRpcException { + + OFBizXmlRpcHttpRequestConfigImpl requestConfig = (OFBizXmlRpcHttpRequestConfigImpl) xmlRpcReq.getConfig(); + LocalDispatcher dispatcher = requestConfig.getDispatcher(); + DispatchContext dctx = dispatcher.getDispatchContext(); String serviceName = xmlRpcReq.getMethodName(); ModelService model = null; try { model = dctx.getModelService(serviceName); } catch (GenericServiceException e) { throw new XmlRpcException(e.getMessage(), e); } // check remote invocation security @@ -272,20 +277,22 @@ public class XmlRpcEventHandler extends XmlRpcHttpServer implements EventHandler Debug.logError(ServiceUtil.getErrorMessage(resp), module); throw new XmlRpcException(ServiceUtil.getErrorMessage(resp)); } // return only definied parameters return model.makeValid(resp, ModelService.OUT_PARAM, false, null); } protected Map<String, Object> getContext(XmlRpcRequest xmlRpcReq, String serviceName) throws XmlRpcException { ModelService model; + OFBizXmlRpcHttpRequestConfigImpl requestConfig = (OFBizXmlRpcHttpRequestConfigImpl) xmlRpcReq.getConfig(); + LocalDispatcher dispatcher = requestConfig.getDispatcher(); try { model = dispatcher.getDispatchContext().getModelService(serviceName); } catch (GenericServiceException e) { throw new XmlRpcException(e.getMessage(), e); } // context placeholder Map<String, Object> context = new HashMap<String, Object>(); if (model != null) { @@ -350,11 +357,25 @@ public class XmlRpcEventHandler extends XmlRpcHttpServer implements EventHandler public OutputStream newOutputStream() throws IOException { response.setContentType("text/xml"); return response.getOutputStream(); } public void close() throws IOException { response.getOutputStream().close(); } } + + class OFBizXmlRpcHttpRequestConfigImpl extends XmlRpcHttpRequestConfigImpl { + private LocalDispatcher dispatcher; + + public OFBizXmlRpcHttpRequestConfigImpl (HttpServletRequest request) { + dispatcher = (LocalDispatcher) request.getAttribute("dispatcher"); + } + + public LocalDispatcher getDispatcher() { + return dispatcher; + } + } + + }