I'm trying to build a web service that accepts a number of variables used to build the path for Bing query API. For some reason, if I build the URI my flow recognizes that the new URI is assigned appropriately to the payload, but when I assign the payload to the out-bound HTTP endpoint, it fails.
<flow name="BingQuery" doc:name="BingQuery">
<http:inbound-endpoint exchange-pattern="one-way" host="localhost" port="8082" doc:name="HTTP" />
<set-variable variableName="query" doc:name="Variable" value="#[header:INBOUND:query]"/>
<set-variable variableName="numResults" doc:name="Variable" value="#[header:INBOUND:top]"/>
<set-variable variableName="offsetResults" doc:name="Variable" value="#[header:INBOUND:offset]"/>
<scripting:component doc:name="Groovy">
<scripting:script engine="Groovy">
<scripting:text><![CDATA[def query = message.getInvocationProperty("query")
def numResults = message.getInvocationProperty("numResults")
def offsetResults = message.getInvocationProperty("offsetResults")
def path = "Data.ashx/Bing/Search/v1/Web?Query=" + "$query" + "&WebFileType=%27PDF%27&\$top=" + "$numResults" + "&\$skip=" + "$offsetResults" + "&\$format=Json"
println "$path"
message.setProperty("pathVar","$path")
return null;]]></scripting:text>
</scripting:script>
</scripting:component>
<logger level="INFO" doc:name="Logger" message="#[header:OUTBOUND:pathVar]"/>
<https:outbound-endpoint exchange-pattern="request-response"
host="api.datamarket.azure.com" port="443" path="#[header:OUTBOUND:pathVar]"
user="*****" password="******"
doc:name="Bing" /> ...
The exception I get is
ERROR 2012-10-25 14:14:26,250 [[poll_directory].BingQuery.stage1.02] org.mule.exception.DefaultMessagingExceptionStrategy:
********************************************************************************
Message : Failed to transform from "json" to "java.util.Map"
Code : MULE_ERROR-65110
--------------------------------------------------------------------------------
Exception stack is:
1. Unexpected character ('T' (code 84)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')
at [Source: java.io.InputStreamReader@73b62d67; line: 1, column: 2] (org.codehaus.jackson.JsonParseException)
org.codehaus.jackson.JsonParser:1291 (null)
2. Failed to transform from "json" to "java.util.Map" (org.mule.api.transformer.TransformerException)
org.mule.module.json.transformers.JsonToObject:136 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/transformer/TransformerException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
org.codehaus.jackson.JsonParseException: Unexpected character ('T' (code 84)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')
at [Source: java.io.InputStreamReader@73b62d67; line: 1, column: 2]
at org.codehaus.jackson.JsonParser._constructError(JsonParser.java:1291)
at org.codehaus.jackson.impl.JsonParserMinimalBase._reportError(JsonParserMinimalBase.java:385)
at org.codehaus.jackson.impl.JsonParserMinimalBase._reportUnexpectedChar(JsonParserMinimalBase.java:306)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
There has to be a simple reason it isn't working and I'm sure it's just because I don't know the proper syntax yet in Mule. I also know there is probably a better way to do this using MEL versus Groovy, but I'm not familiar enough with MEL to do it yet.
SOLUTION
Turns out some of the characters of the User property and Password property were being encoded before being sent. Putting that key into a variable before passing to the User & Password property prevents that and led to success.
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:scripting="http://www.mulesoft.org/schema/mule/scripting" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:json="http://www.mulesoft.org/schema/mule/json"
xmlns:vm="http://www.mulesoft.org/schema/mule/vm" xmlns:http="http://www.mulesoft.org/schema/mule/http"
xmlns:https="http://www.mulesoft.org/schema/mule/https" xmlns:file="http://www.mulesoft.org/schema/mule/file"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans" xmlns:core="http://www.mulesoft.org/schema/mule/core"
version="CE-3.3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd
http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/current/mule-vm.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/https http://www.mulesoft.org/schema/mule/https/current/mule-https.xsd
http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/current/mule-file.xsd
http://www.mulesoft.org/schema/mule/scripting http://www.mulesoft.org/schema/mule/scripting/current/mule-scripting.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd ">
<configuration doc:name="Configuration">
<expression-language>
<import class="org.mule.util.StringUtils" />
</expression-language>
</configuration>
<flow name="BingQuery" doc:name="BingQuery">
<http:inbound-endpoint exchange-pattern="one-way" host="localhost" port="8082" doc:name="HTTP" />
<set-variable variableName="query" doc:name="Variable" value="#[header:INBOUND:query]"/>
<set-variable variableName="numResults" doc:name="Variable" value="#[header:INBOUND:top]"/>
<set-variable variableName="offsetResults" doc:name="Variable" value="#[header:INBOUND:offset]"/>
<scripting:component doc:name="Groovy">
<scripting:script engine="Groovy">
<scripting:text><![CDATA[def query = message.getInvocationProperty("query")
def numResults = message.getInvocationProperty("numResults")
def offsetResults = message.getInvocationProperty("offsetResults")
def path = "Data.ashx/Bing/Search/v1/Web?Query=" + "$query" + "&WebFileType=%27PDF%27&\$top=" + "$numResults" + "&\$skip=" + "$offsetResults" + "&\$format=Json"
println "$path"
message.setProperty("pathVar","$path")
message.setProperty("APIIdentifier","*****")
return null;]]></scripting:text>
</scripting:script>
</scripting:component>
<https:outbound-endpoint exchange-pattern="request-response"
host="api.datamarket.azure.com" port="443" path="#[header:OUTBOUND:pathVar]"
user="#[header:OUTBOUND:APIIdentifier]" password="#[header:OUTBOUND:APIIdentifier]"
doc:name="Bing" />
<json:json-to-object-transformer
returnClass="java.util.Map" doc:name="JSON to Object" />
<expression-transformer expression="#[message.payload.d.results]"
doc:name="Expression" />
<collection-splitter doc:name="Collection Splitter" />
<vm:outbound-endpoint exchange-pattern="one-way"
path="fileWriter" doc:name="VM" />
</flow>
<flow name="RestProcessor" doc:name="RestProcessor">
<vm:inbound-endpoint exchange-pattern="one-way"
path="fileWriter" doc:name="VM" />
<set-variable variableName="fileName" value="#[message.payload.ID].pdf"
doc:name="Variable" />
<http:rest-service-component
serviceUrl="#[joinChar=message.payload.Url.contains('?')?'&':'?' ; StringUtils.join(new String[]{message.payload.Url,(String)joinChar,'followRedirects=true'})]"
httpMethod="GET">
<http:error-filter>
<expression-filter expression="#[Integer.valueOf(message.inboundProperties['http.status']) >= 400]"></expression-filter>
</http:error-filter>
</http:rest-service-component>
<file:outbound-endpoint path="/home/administrator/Documents"
outputPattern="#[flowVars.fileName]" responseTimeout="10000"
mimeType="application/pdf" doc:name="File" />
</flow>
</mule>