| Summary: | RestClientService.invokeRemoteCall throws exception on successful HTTP operation that returns HTTP status other than 200 | ||
|---|---|---|---|
| Product: | [RT] ECF | Reporter: | Dirk Olmes <dirk.olmes> |
| Component: | ecf.remoteservices | Assignee: | Scott Lewis <slewis> |
| Status: | RESOLVED FIXED | QA Contact: | |
| Severity: | normal | ||
| Priority: | P3 | CC: | slewis |
| Version: | unspecified | ||
| Target Milestone: | 3.5.1 | ||
| Hardware: | PC | ||
| OS: | Linux | ||
| Whiteboard: | |||
I agree the logic in RestClientService needs to be generalized (to support at least 20* response values), but I would like to discuss with you how best to accomplish that.
Ideally, I would add a protected method in RestClientService...something like this:
protected boolean responseOk(int responseCode) {
return (responseCode == HttpStatus.SC_OK || responseCode == HttpStatus.SC_CREATED || ...);
}
and then use this method in the RestClientService.invokeRemoteCall method. This would fix this particular issue, and it would allow things to easily be customized.
However, ECF isn't planning a minor release for some time, and an addition like the above constitutes an API addition...and so would require a minor release. So even if this addition is made, it won't be released for some time.
Another option is to simply embed the test against multiple response codes in the invokeRemoteCall method. This would probably satisfy your needs for this bug, but would not be very general. But it could be released as a bug fix only, and so could be released as part of ECF 3.5.1 (due near end of May...we're still discussing the date on ecf-dev mailing list).
Another possibility in the short term, BTW, is that you simply override invokeRemoteCall and implement it yourself in your own subclass of RestClientService.
I think what I will do is to add the logic for testing against all response codes in invokeRemoteCall. If you need an immediate fix (i.e. before ECF 3.5.1) then you can override invokeRemoteCall and implement the proper test in your implementation.
Fix as described in comment 1 released to master. Resolving as fixed. Dirk if you have comments about the comments and questions in comment 1 please continue to make them on this bug...or on ecf-dev. actually resolving. Scott, thanks for fixing this issue so quickly. Pulling the latest update I see that you made the isResponseOk() method private. In the comment above you're talking about making this method protected which is much more friendly for subclassers. Was this just an oversight or did you do it on purpose? (In reply to comment #4) > Scott, thanks for fixing this issue so quickly. Pulling the latest update I see > that you made the isResponseOk() method private. In the comment above you're > talking about making this method protected which is much more friendly for > subclassers. Was this just an oversight or did you do it on purpose? I did it on purpose (made it private), because otherwise this constitutes an API change, and we would have to have release review, etc., etc. prior to release. |
Build Identifier: org.eclipse.ecf.remoteservice.rest_2.1.0.v20110313-1843 I use ECF's remote service API to access a remote REST service. New resources are created using a POST request. Upon successful creation of the remote resource the service returns HTTP stauts code 201 (Created) which falls into the "Successful" category of HTTP status codes. The invokeRemoteCall method in RestClientService only checks for HTTP status 200 though (line 70) and throws an exception for any other status code. This logic should be extended a bit to allow all other 2xx status codes. Reproducible: Always Steps to Reproduce: Sample code using a PUT method to a local couchdb: String dbUrl = COUCH_DB_URL + "sample_database/"; IContainerFactory containerFactory = Activator.getDefault().getContainerFactory(); IContainer container = containerFactory.createContainer(REST_CONTAINER_TYPE, dbUrl); IRemoteServiceClientContainerAdapter adapter = (IRemoteServiceClientContainerAdapter) container.getAdapter(IRemoteServiceClientContainerAdapter.class); IRemoteCallParameter[] parameters = RemoteCallParameterFactory.createParameters("body", null); HttpPutRequestType requestType = new HttpPutRequestType(HttpPutRequestType.STRING_REQUEST_ENTITY, "text/plain"); String uuid = "/8f1f43ef03683be7b24b0de9db001632"; IRemoteCallable callable = RestCallableFactory.createCallable("createDocument", uuid, parameters, requestType); String[] serviceInterfaceNames = new String[] { ICouchDB.class.getName() }; IRemoteCallable[][] remoteCallables = new IRemoteCallable[][] { { callable } }; IRemoteServiceRegistration registration = adapter.registerCallables(serviceInterfaceNames, remoteCallables, null); IRemoteService remoteService = adapter.getRemoteService(registration.getReference()); Object[] callParameters = new Object[] { "{ \"name\" : \"Dirk Olmes\" }" }; IRestCall restCall = RestCallFactory.createRestCall(ICouchDB.class.getName() + ".createDocument", callParameters ); Object result = remoteService.callSync(restCall); System.out.println(result);