Skip to content
This repository was archived by the owner on Sep 28, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 90 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ A backend software, self-hostable and ready to use to power modern apps.

You can access the Kuzzle repository on [Github](https://github.com/kuzzleio/kuzzle)


## SDK Documentation

The complete SDK documentation is available [here](http://docs.kuzzle.io/sdk-reference)
Expand All @@ -24,7 +23,7 @@ https://github.com/kuzzleio/kuzzle-sdk/issues

## Installation

You can configure your android project to get the Kuzzle's android SDK from jcenter in your build.gradle:
You can configure your Android project to get Kuzzle's Android SDK from jcenter in your build.gradle:

buildscript {
repositories {
Expand All @@ -40,6 +39,94 @@ You can configure your android project to get the Kuzzle's android SDK from jcen
compile 'io.kuzzle:sdk-android:2.2.0'
}

## Basic usage

```java
Kuzzle kuzzle = new Kuzzle("host", new ResponseListener<Void>() {
@Override
public void onSuccess(Void object) {
// Handle success
KuzzleDocument doc = new KuzzleDocument(dataCollection);
doc.setContent("foo", "bar").save();
}

@Override
public void onError(JSONObject error) {
// Handle error
}
});
```

## KuzzleDocument

KuzzleDocument is an encapsulation of a JSONObject.

```java
KuzzleDataCollection myCollection = new KuzzleDataCollection(kuzzle, "myNewCollection");
KuzzleDocument myDocument = new KuzzleDocument(myCollection);
// Add properties to the body
myDocument.setContent("foo", "bar");
// Persist the document
myDocument.save();
// Send it on real time (not persistent)
myDocument.publish();
```

## Adding metadata

As stated [here](http://kuzzle.io/api-reference/#sending-metadata) you can add metadata to a subscription.

```java
KuzzleOptions options = new KuzzleOptions();
JSONObject metadata = new JSONObject();
metadata.put("foo", "bar");
options.setMetadata(metadata);
myCollection.subscribe(options);
```

# Login

## Prerequisite

To login using kuzzle you need at least one authentication plugin. You can refer [here](https://github.com/kuzzleio/kuzzle-plugin-auth-passport-local) for a local authentication plugin
or [here](https://github.com/kuzzleio/kuzzle-plugin-auth-passport-oauth) to refer to our OAuth2 plugin.

To know more about how to log in with a Kuzzle SDK, please refer to our [documentation](http://docs.kuzzle.io/sdk-reference/kuzzle/login/)

If you have the kuzzle-plugin-auth-passport-local installed you can login using either the Kuzzle's constructor or the login method.

### Login with an OAuth strategy

If you have an OAUTH plugin like kuzzle-plugin-auth-passport-oauth, you may use the KuzzleWebViewClient class to handle the second authentication phase:

```java
Handler handler = new Handler();
WebView webView = (WebView) findViewById(R.id.webView);
webView.setWebViewClient(kuzzle.getKuzzleWebViewClient());
kuzzle.login("github", new KuzzleResponseListener<JSONObject>() {
@Override
public void onSuccess(final JSONObject object) {
handler.post(new Runnable() {
@Override
public void run() {
try {
if (object.has("headers")) {
webView.loadUrl(object.getJSONObject("headers").getString("Location"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}

@Override
public void onError(JSONObject error) {
Log.e("error", error.toString());
}
});
```

## License

[Apache 2](LICENSE.md)
[Apache 2](LICENSE)
2 changes: 1 addition & 1 deletion src/main/java/io/kuzzle/sdk/core/Collection.java
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ public void scroll(String scrollId, final Options options, final JSONObject filt
options.setScrollId(scrollId);

try {
this.kuzzle.query(makeQueryArgs("document", "scroll"), request, options, new OnQueryDoneListener() {
this.kuzzle.query(this.kuzzle.buildQueryArgs("document", "scroll"), request, options, new OnQueryDoneListener() {
@Override
public void onSuccess(JSONObject object) {
try {
Expand Down
37 changes: 36 additions & 1 deletion src/main/java/io/kuzzle/sdk/responses/SearchResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import android.support.annotation.NonNull;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

Expand Down Expand Up @@ -99,16 +100,19 @@ public JSONObject getFilters() {
public void fetchNext(ResponseListener<SearchResult> listener) {
JSONObject filters;
Options options;

try {
options = new Options(this.options);
} catch (JSONException e) {
throw new RuntimeException(e);
}
options.setPrevious(this);

// retrieve next results with scroll if original search use it
if (options.getScrollId() != null) {
if(this.fetchedDocument >= this.getTotal()) {
if (this.fetchedDocument >= this.getTotal()) {
listener.onSuccess(null);

return;
}

Expand All @@ -125,6 +129,37 @@ public void fetchNext(ResponseListener<SearchResult> listener) {
return;
}

// retrieve next results using ES's search_after
if (options.getSize() != null && this.filters.has("sort")) {
if (this.fetchedDocument >= this.getTotal()) {
listener.onSuccess(null);

return;
}

if (options.getFrom() != null) {
options.setFrom(null);
}

try {
JSONArray searchAfter = new JSONArray();

for (int i = 0; i < this.filters.getJSONArray("sort").length(); i++) {
Document doc = this.getDocuments().get(this.getDocuments().size() - 1);
searchAfter.put(doc.getContent().get(this.filters.getJSONArray("sort").getJSONObject(i).keys().next()));
}

this.filters.put("search_after", searchAfter);
} catch (JSONException e) {
throw new RuntimeException(e);
}

this.collection.search(this.filters, options, listener);

return;
}

// retrieve next results with from/size if original search use it
if (options.getFrom() != null && options.getSize() != null) {
try {
filters = new JSONObject(this.filters.toString());
Expand Down
57 changes: 48 additions & 9 deletions src/test/java/io/kuzzle/test/responses/SearchResultTest.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package io.kuzzle.test.responses;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;

import java.net.URISyntaxException;
import java.util.ArrayList;
Expand All @@ -15,7 +17,6 @@
import io.kuzzle.sdk.enums.Mode;
import io.kuzzle.sdk.listeners.ResponseListener;
import io.kuzzle.sdk.responses.SearchResult;
import io.kuzzle.sdk.security.Profile;
import io.kuzzle.sdk.state.States;
import io.kuzzle.test.testUtils.KuzzleExtend;
import io.socket.client.Socket;
Expand All @@ -34,8 +35,6 @@ public class SearchResultTest {
private ResponseListener listener;
private long total;
private ArrayList<Document> documents;
private String documentId;
private JSONObject documentContent;
private Options options;
private String scrollId;
private String scroll;
Expand All @@ -53,13 +52,12 @@ public void setUp() throws URISyntaxException {
collection = new Collection(kuzzle, "test", "index");
listener = mock(ResponseListener.class);
total = (long) 42;
documentId = "someDocumentId";
documents = new ArrayList<Document>();
documents = new ArrayList<>();
scrollId = "someScrollId";
scroll = "someScroll";
try {
documentContent = new JSONObject().put("some", "content");
documents.add(new Document(collection, documentId, documentContent));
documents.add(new Document(collection, "foo", new JSONObject().put("name", "John").put("age", 42)));
documents.add(new Document(collection, "bar", new JSONObject().put("name", "Michael").put("age", 36)));
} catch(JSONException e) {
throw new RuntimeException(e);
}
Expand All @@ -74,7 +72,48 @@ public void checkConstructorArguments() {
assertEquals(searchResult.getAggregations(), null);
assertEquals(searchResult.getOptions(), options);
assertEquals(searchResult.getFilters(), null);
assertEquals(searchResult.getFetchedDocument(), (long) 1);
assertEquals(searchResult.getFetchedDocument(), (long) 2);
}

@Test
public void fetchNextBySearchAfter() throws JSONException {
Options localOptions = new Options(options);
localOptions
.setSize((long) 2);

JSONObject filters = new JSONObject()
.put("sort", new JSONArray()
.put(new JSONObject()
.put("age", "desc")
)
.put(new JSONObject()
.put("name", "asc")
)
);

collection = spy(collection);
SearchResult searchResult = new SearchResult(collection, total, documents, null, localOptions, filters);

searchResult.fetchNext(listener);

JSONObject expectedFilters = new JSONObject()
.put("search_after", new JSONArray()
.put(36)
.put("Michael")
)
.put("sort", new JSONArray()
.put(new JSONObject()
.put("age", "desc")
)
.put(new JSONObject()
.put("name", "asc")
)
);

ArgumentCaptor argument = ArgumentCaptor.forClass(io.kuzzle.sdk.core.Kuzzle.QueryArgs.class);
verify(collection).search((JSONObject) argument.capture(), any(Options.class), eq(listener));

assertEquals(argument.getValue().toString(), expectedFilters.toString());
}

@Test
Expand All @@ -89,7 +128,7 @@ public void fetchNextByScroll() throws JSONException {

searchResult.fetchNext(listener);

verify(collection).scroll(eq(scrollId), any(Options.class), eq((JSONObject) null), eq(listener));
verify(collection).scroll(eq(scrollId), any(Options.class), any(JSONObject.class), eq(listener));
}

@Test
Expand Down