Get Changes Feed response through Spring RestTemplate

Hi,

We have been trying to read the changes feed response from the couchbase sync gateway using the Spring RestTemplate library. The get changes feed URL being used is: http://localhost:4985/default/_changes?feed=continuous&timeout=1000.

Meanwhile, using a standard HTTP proxy tool, fired the same query (mentioned above) and the response showed all the doc changes with HTTP header content-type as application/octet-stream. Hence, we are using the MappingJacksonHttpMessageConverter with supportedMediaTypes as JSON and octet-stream.

We have also created a VO object to hold the changes feed which looks like:
public class KnChanges {
private long seq;
private String id;
private List changes;

However, when the restTemplate.getForObject(url, KnChanges.class) is invoked, only the first change is seen in the response. When tried printing the response entity object, only one change feed was being shown.

Can you please help in this regard? How to read the changes feed list? What data structure to use?

Note: Even used the KnChanges[] as the return object type. Also tried Object.class and then using Map<key,value> to read the response. But since the actual response itself is not giving all changes list except first one, the getForObject call will also return the same.

Hi @harsha_athreya,

I’m looking into this but can I ask what functionality you are building out of the changes feed?

Depending on the use case, it could be much easier to use webhooks. Which is available in the current 1.1 developer preview and will be GA shortly.

James

Thanks @jamiltz for the quick and prompt response.

We are trying to achieve a functionality where depending on the changes feed received from syncGW, we will be updating our corresponding relational database records. Thus keeping the relational data as well as the couchbase data in sync. We have some additional business logic involved though.

We had infact gone through the Webhooks wiki earlier. The feature will be really helpful but meanwhile we needed the functionality implemented in a very short time from now. Can you please let know as to when the GA release is planned? Also, if you can get back on the initial query, it would be really of great help for us.

Thanks
Harsha

Ok thanks for the details.

Sorry I don’t know the Spring RestTemplate library enough to help with the implementation in your application. Could you share a gist with the method handling the changes feed response? I will ask a colleague who knows more about Spring :slight_smile: It’s definitely working as expected using curl?

In your case, you might prefer to add documents to the relational database in batches so perhaps for this use case, the changes feed is a good fit.

FYI, you can find a simple tutorial on webhooks here too 02-gcm-webhook of https://github.com/couchbaselabs/couchbase-by-example for handling push notifications.

James

Thanks.

Please find the code snippet below that is being used to get changes feed:

List<HttpMessageConverter<?>> mc = restTemplate.getMessageConverters();
MappingJacksonHttpMessageConverter json = new MappingJacksonHttpMessageConverter();

List supportedMediaTypes = new ArrayList();
supportedMediaTypes.add(new MediaType(“application”, “json”, Charset.forName(“UTF-8”)));
supportedMediaTypes.add(new MediaType(“application”, “octet-stream”, Charset.forName(“UTF-8”)));
json.setSupportedMediaTypes(supportedMediaTypes);

mc.add(json);
restTemplate.setMessageConverters(mc);

HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setAccept(supportedMediaTypes);
requestEntity = new HttpEntity (requestHeaders);

The main place where the response JSON to object conversion happens is at the line below:
ResponseEntity responseEntity = restTemplate.exchange(
“http://localhost:4985/default/_changes?feed=continuous&timeout=1000”,
HttpMethod.GET, requestEntity, String.class);
If the mapped object is String, then getting all the changes feed. Whereas, if I happen to use a custom Value object, somethings like:
public class KnChanges {
private long seq;
private String id;
private List changes;

with getter and setter methods, then I’m getting only the first doc change details. Even if the KnChanges[] (array) is used, only the first change is obtained.

Please help, thanks once again.

Regards
Harsha

Basically, the trouble being faced related to get changes feed is that… usually when we have a collection or array, something like below:
[
{
“id”:100,
“name”:“foo1”
},
{
“id”:200,
“name”:“foo2”
}
]

Whereas, the response JSON for getChanges looks like this:
{“seq”:1,“id”:“Test1”,“changes”:[{“rev”:“1-52f5cdf008ecfbadf621c2939af7bd80”}]}
{“seq”:2,“id”:“Test2”,“changes”:[{“rev”:“1-8ce403a89dc5e7cb4187a16941b3fb7d”}]}

The changes list is not encapsulated within [] brackets to represent as list. Hence, not able to convert this as List through SpringTemplate.

Regards
Harsha

When you request a non-continuous changes feed, you’ll get back the changes in a single closed JSON object - e.g.

{"results":[    
{
    "changes": [
 {"seq":114,"id":"ownerdoc3","changes":[{"rev":"1-17372425df280847828565c898bc642b"}]},
 {"seq":115,"id":"ownerdoc4","changes":[{"rev":"1-e57c147bd1398b355d8a8448721e6364"}]}
],
"last_seq":"180"}

When you request a continuous changes feed, however, Sync Gateway is going to send the changes in form you described - as individual change entries, where each entry is a complete JSON document:

{"seq":113,"id":"ownerdoc2","changes":[{"rev":"1-b1a0ebf5b5644cf8c5edf6f5a2eedd40"}]}
{"seq":114,"id":"ownerdoc3","changes":[{"rev":"1-17372425df280847828565c898bc642b"}]}

Since it’s a continuous stream, embedding the entries within a larger JSON object (like in the non-continuous case) would just result in an open JSON array that never gets closed. If you want to process a continuous stream, you’ll have to modify your code to work the stream entries individually, as they arrive.

1 Like

Thanks @adamf for the prompt response. Sure, will work out the solution based on your inputs :smile:

Thanks @adamf and @jamiltz!

We are able to get the changes freed using the Webhooks feature of the recently release Sync G/w 1.1. However we had a few queries regarding the feed that is received in the Webhooks HTTP handler:

  1. In case of webhook feed is dropped by Sync-Gateway due to some reason, how does the application know about it? Is there anyway Sync-Gateway can inform about message drop?

  2. While doing data-sync (from Couch-lite to Sync-Gateway), does couch-lite maintains same order for document sync as their insertion/creation order into couch-lite?

  3. As it appears from local webhook testing, Sync Gateway is not sending seq_no. in webhook trigger, then how does backend server-application order the messages for delivery?

Can you please clarify?
Thanks

If there’s an error when trying to POST a webhook event, there will be a warning logged in the Sync Gateway logs. There currently isn’t any retry or delivery guarantee to the webhook target, although that’s on the roadmap for a future release.

No, the client cannot assume any ordering guarantee.

Webhook events are posted when Sync Gateway completes the write of the document to it’s backing data store (e.g. Couchbase Server). As with the previous item, there’s no ordering guarantee.

Hi Harsha,

Using this process did you find any solutions.?