REST services Consume java action results in invalid query

0
I'm having a weird issue with RestServices module. I'm trying to utilized Google Maps Distance Matrix API( https://developers.google.com/maps/documentation/distance-matrix/intro ). I have set up the correct domain model configuration, and I used the RestServices.request Java action. If I set the request data such as that there is only one origin and one destination, the Java action works correctly and returns the data as intended. However, if I have more than one origin and destination, the Java action returns an error. Here is a Stack trace: java.lang.IllegalArgumentException: Invalid uri 'https://maps.googleapis.com/maps/api/distancematrix/json?origins=place_id:ChIJE7y9bABPzDER3UogdqNmbtg|place_id:ChIJm21YdodMzDERJW_y1EmlGV4&destinations=place_id:ChIJm21YdodMzDERJW_y1EmlGV4|place_id:ChIJS9Y7UY5JzDERudeQ8EDhRmw&key=YOUR_API_KEY': Invalid query     at org.apache.commons.httpclient.HttpMethodBase.<init>(HttpMethodBase.java:222)     at org.apache.commons.httpclient.methods.GetMethod.<init>(GetMethod.java:89)     at restservices.consume.RestConsumer.doRequest(RestConsumer.java:246)     at restservices.consume.RestConsumer.request(RestConsumer.java:488)     at restservices.actions.request.executeAction(request.java:40)     at restservices.actions.request.executeAction(request.java:1)     at com.mendix.systemwideinterfaces.core.UserAction.execute(UserAction.java:50)     at com.mendix.basis.actionmanagement.CoreActionHandlerImpl.doCall(CoreActionHandlerImpl.scala:73)     at com.mendix.basis.actionmanagement.CoreActionHandlerImpl.call(CoreActionHandlerImpl.scala:53)     at com.mendix.core.actionmanagement.CoreAction.call(CoreAction.java:51)     at com.mendix.basis.actionmanagement.ActionManager$1.execute(ActionManager.java:170)     at com.mendix.util.classloading.Runner.doRunUsingClassLoaderOf(Runner.java:33)     at com.mendix.basis.actionmanagement.ActionManager.executeSync(ActionManager.java:174)     at com.mendix.basis.component.InternalCore.execute(InternalCore.java:531)     at com.mendix.modules.microflowengine.actions.actioncall.JavaAction.execute(JavaAction.scala:52)     at com.mendix.modules.microflowengine.microflow.impl.MicroflowObject.execute(MicroflowObject.java:47)     at com.mendix.modules.microflowengine.microflow.impl.MicroflowImpl.executeAfterBreakingIfNecessary(MicroflowImpl.java:200)     at com.mendix.modules.microflowengine.microflow.impl.MicroflowImpl.executeAction(MicroflowImpl.java:157)     at com.mendix.systemwideinterfaces.core.UserAction.execute(UserAction.java:50)     at com.mendix.basis.actionmanagement.CoreActionHandlerImpl.doCall(CoreActionHandlerImpl.scala:73)     at com.mendix.basis.actionmanagement.CoreActionHandlerImpl.call(CoreActionHandlerImpl.scala:53)     at com.mendix.core.actionmanagement.CoreAction.call(CoreAction.java:51)     at com.mendix.basis.actionmanagement.ActionManager$1.execute(ActionManager.java:170)     at com.mendix.util.classloading.Runner.doRunUsingClassLoaderOf(Runner.java:33)     at com.mendix.basis.actionmanagement.ActionManager.executeSync(ActionManager.java:174)     at com.mendix.basis.component.InternalCore.execute(InternalCore.java:531)     at com.mendix.webui.actions.client.ExecuteAction.execute(ExecuteAction.java:143)     at com.mendix.webui.requesthandling.ClientRequestHandler$$anonfun$handleRequest$1.apply$mcV$sp(ClientRequestHandler.scala:307)     at com.mendix.webui.requesthandling.ClientRequestHandler$$anonfun$handleRequest$1.apply(ClientRequestHandler.scala:293)     at com.mendix.webui.requesthandling.ClientRequestHandler$$anonfun$handleRequest$1.apply(ClientRequestHandler.scala:293)     at com.mendix.basis.actionmanagement.IMonitoredAction$$anon$1.execute(IMonitoredAction.scala:47)     at com.mendix.util.classloading.Runner.doRunUsingClassLoaderOf(Runner.java:33)     at com.mendix.basis.actionmanagement.IMonitoredAction$class.monitor(IMonitoredAction.scala:49)     at com.mendix.webui.requesthandling.ClientRequestHandler$ClientMonitoredAction.monitor(ClientRequestHandler.scala:408)     at com.mendix.webui.requesthandling.ClientRequestHandler.handleRequest(ClientRequestHandler.scala:293)     at com.mendix.webui.requesthandling.ClientRequestHandler.handleActionWithSessionRequired(ClientRequestHandler.scala:235)     at com.mendix.webui.requesthandling.ClientRequestHandler.handleAction(ClientRequestHandler.scala:202)     at com.mendix.webui.requesthandling.ClientRequestHandler.liftedTree1$1(ClientRequestHandler.scala:101)     at com.mendix.webui.requesthandling.ClientRequestHandler.processRequest(ClientRequestHandler.scala:93)     at com.mendix.externalinterface.connector.RequestHandler.doProcessRequest(RequestHandler.java:40)     at com.mendix.external.connector.MxRuntimeConnector$1.execute(MxRuntimeConnector.java:70)     at com.mendix.external.connector.MxRuntimeConnector$1.execute(MxRuntimeConnector.java:67)     at com.mendix.util.classloading.Runner.doRunUsingClassLoaderOf(Runner.java:33)     at com.mendix.external.connector.MxRuntimeConnector.processRequest(MxRuntimeConnector.java:73)     at com.mendix.basis.impl.MxRuntimeImpl.processRequest(MxRuntimeImpl.java:885)     at com.mendix.m2ee.appcontainer.server.handler.RuntimeHandler.handle(RuntimeHandler.java:41)     at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:52)     at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)     at org.eclipse.jetty.server.Server.handle(Server.java:368)     at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:489)     at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:953)     at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:1014)     at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:861)     at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:240)     at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)     at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:628)     at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52)     at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)     at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)     at java.lang.Thread.run(Thread.java:745)   I'm not sure what is happening here. Anyone has encountered this issue before?
asked
1 answers
2

Yes, I have encountered this issue before. This cause lies in a library the REST module uses (and/or Google using a | character in their URL). I have created a brilliant hack (*cough*). What I did:

 

* Replace all pipe characters from the URL with ===

* Edit the doRequest() method in the Java file RestConsumer.java, look for the code between //StartByRom andd //EndByRom

 

	private static HttpResponseData doRequest(String method, String url, Map<String, String> requestHeaders,
			Map<String, String> params, RequestEntity requestEntity, Predicate<InputStream> onSuccess) throws HttpException, IOException {
		if (RestServices.LOGCONSUME.isDebugEnabled())
			RestServices.LOGCONSUME.debug("Fetching '" + url + "'..");
		
		HttpMethodBase request = null;

		try {
			if (params != null && !"POST".equals(method)) {
				//append params to url. Do *not* use request.setQueryString; that will override any args already in there
				for(Entry<String, String> e : params.entrySet())
					url = Utils.appendParamToUrl(url, e.getKey(), e.getValue());
			}
			
			if ("GET".equals(method))
				request = new GetMethod(url);
			else if ("DELETE".equals(method))
				request = new DeleteMethod(url);
			else if ("POST".equals(method)) 
				request = new PostMethod(url);
			else if ("PUT".equals(method)) 
				request = new PutMethod(url);
			else 
				throw new IllegalStateException("Unsupported method: " + method);

			request.getParams().setCookiePolicy(CookiePolicy.IGNORE_COOKIES);
			request.setRequestHeader(RestServices.HEADER_ACCEPT, RestServices.CONTENTTYPE_APPLICATIONJSON);
			
			if (requestHeaders != null) for(Entry<String, String> e : requestHeaders.entrySet())
				request.addRequestHeader(e.getKey(), e.getValue());
			includeHeaders(request);
			
			if (params != null && request instanceof PostMethod) 
				((PostMethod)request).addParameters(mapToNameValuePairs(params));
			
			if (request instanceof PostMethod && requestEntity != null)
				((PostMethod)request).setRequestEntity(requestEntity);
			else if (request instanceof PutMethod && requestEntity != null)
				((PutMethod)request).setRequestEntity(requestEntity);
			//StartByRom
			RestServices.LOGCONSUME.debug("Overriding URL");
			String newURL = url.replace("===", "|");
			request.setURI(new URI(newURL, false));
			//EndByRom
			
			int status = client.executeMethod(request);

			Header responseEtag = request.getResponseHeader(RestServices.HEADER_ETAG);
			HttpResponseData response = new HttpResponseData(method, url, status, responseEtag == null ? null : responseEtag.getValue(), request.getResponseHeaders());

			InputStream instream = request.getResponseBodyAsStream(); 
			if (onSuccess != null && status >= 200 && status < 300 && instream != null) //NO CONENT doesnt yield a stream..
				onSuccess.apply(instream);
			else if (instream != null)
				response.setBody(IOUtils.toString(instream));
			
			if (RestServices.LOGCONSUME.isDebugEnabled())
			{
				RestServices.LOGCONSUME.debug(response);
			}	
			
			return response;
		}

 

You should probably file a bug report here...

answered