I am trying to send some messages through a local RESTful web service. The URL is allowed to contain query parameters. My processor for the REST method is not seeing those query parameters. Does anyone see what I am doing wrong?
I am using Camel 2.16.0.
My Blueprint routes XML is:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel-cxf="http://camel.apache.org/schema/blueprint/cxf"
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
http://www.osgi.org/xmlns/1.0.0/blueprint.xsd
http://camel.apache.org/schema/blueprint/cxf
http://camel.apache.org/schema/cxf/camel-cxf-blueprint.xsd">
<bean id="issPreprocessor" class="com.rockwellcollins.railwaynet.messagerouter.routing.IssPreprocessor"/>
<bean id="webServiceProcessor" class="com.rockwellcollins.railwaynet.messagerouter.routing.WebServiceProcessor"/>
<bean id="packageWebServiceReplyForIss" class="com.rockwellcollins.railwaynet.messagerouter.routing.PackageWebServiceReplyForIss"/>
<!-- These two cooperate to send web service requests to the mocked
out web service substitute. The crewMock bean handles requests sent
to the jetty service stand-in; the webService rsClient sends the
request.
-->
<bean id="steve" class="messagerouter.EmployeeInfo">
<argument value="Stephen"/>
<argument value="D."/>
<argument value="Huston"/>
<argument value="1234"/>
</bean>
<bean id="crewMock" class="messagerouter.CrewServiceMock">
<property name="info">
<map>
<entry key="rraa">
<map>
<entry key="steve" value-ref="steve"/>
</map>
</entry>
</map>
</property>
</bean>
<camel-cxf:rsClient id="webService" address="http://localhost:9000" serviceClass="com.rockwellcollins.railwaynet.messagerouter.routing.WebService" loggingFeatureEnabled="true"/>
<camelContext id="rraaCamelContext" xmlns="http://camel.apache.org/schema/blueprint">
<dataFormats>
<json id="IssRequest" library="Jackson"/>
</dataFormats>
<!-- Mocked out web service -->
<route id="CrewMock">
<from uri="jetty:http://localhost:9000?matchOnUriPrefix=true"/>
<to uri="cxfbean:crewMock"/>
</route>
<route id="rraaIss">
<from uri="seda:from_rraa"/>
<process ref="issPreprocessor"/>
<unmarshal ref="IssRequest"/>
<process ref="webServiceProcessor"/>
<to uri="cxfrs:bean:webService"/>
<process ref="packageWebServiceReplyForIss"/>
<to uri="seda:to_rraa"/>
</route>
</camelContext>
</blueprint>
My WebService class to set up the request is:
public class WebServiceProcessor implements Processor {
@Override
public void process(Exchange exchange) throws Exception {
exchange.setPattern(ExchangePattern.InOut);
Message in = exchange.getIn();
// Using proxy client API; needs the op name.
in.setHeader(CxfConstants.CAMEL_CXF_RS_USING_HTTP_API, Boolean.FALSE);
in.setHeader(CxfConstants.OPERATION_NAME, "verifyEmployee");
VerifyEmployeeRequest req = in.getBody(VerifyEmployeeRequest.class);
MessageContentsList params = new MessageContentsList();
params.add(req.getHeader().getScac());
params.add(req.getBody().getEmployeeID());
params.add(req.getBody().getPin());
params.add(req.getBody().getReason());
in.setBody(params);
}
}
and my interface class for the service invocation is:
@Path(value="/rest")
public interface WebService {
@GET
@Path(value="/authentication/{scac}/employees/{id}?pin={pin}&reason={reason}")
@Produces({ MediaType.APPLICATION_JSON })
public String verifyEmployee(@PathParam("scac") String scac,
@PathParam("id") String id,
@PathParam("pin") String pin,
@PathParam("reason") String reason);
}
The class to process the request is:
@Path("/rest")
public class CrewServiceMock {
// scac -> { id -> employeeInfo }
private Map<String, Map<String, EmployeeInfo> > info;
public Map<String, Map<String, EmployeeInfo> > getInfo()
{ return info; }
public void setInfo(Map<String, Map<String, EmployeeInfo> > info)
{ this.info = info; }
@GET
@Path("/authentication/{scac}/employees/{id}")
public Response getAuth(@PathParam("scac") String scac,
@PathParam("id") String id,
@QueryParam("reason") String reason,
@QueryParam("pin") String pin) {
Map<String, EmployeeInfo> employees = info.get(scac);
if (employees == null) {
return Response.status(404).build();
}
System.out.println(employees);
System.out.println("id is " + id);
System.out.println("scac is " + scac);
System.out.println("reason is " + reason);
EmployeeInfo emp = (EmployeeInfo)employees.get(id);
if (emp == null) {
return Response.status(404).entity("{ message: \"id not found\" }").build();
}
return Response.status(200).entity("{ \"employeeID\": " + id + ", \"employeeName\": { \"first\": \"" + emp.getFirstName() + "\", \"middle\": \"" + emp.getMiddleName() + "\", \"last\": \"" + emp.getLastName() + "\" } }").build();
}
}
When I run this, I see the following in the test output:
ID: 1 Address: http://localhost:9000/rest/authentication/rraa/employees/steve%3Fpin=1234&reason=INIT Http-Method: GET Content-Type: application/xml
{steve=messagerouter.EmployeeInfo@1dd62581} id is steve?pin=1234&reason=INIT scac is rraa reason is null
So, the query parameters are apparently not being parsed out - they're attached to the last path parameter. Am I doing something wrong?
Your interface has 4 path parameters instead of 2 path and 2 query parameters, it should be:
@Path(value="/rest")
public interface WebService {
@GET
@Path(value="/authentication/{scac}/employees/{id}")
@Produces({ MediaType.APPLICATION_JSON })
public String verifyEmployee(@PathParam("scac") String scac,
@PathParam("id") String id,
@QueryParam("pin") String pin,
@QueryParam("reason") String reason);
}