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 <[email protected]>
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;
+ }
+ }
+
+
}