Skip to content

Commit

Permalink
Merge pull request #73 from kuzzleio/call-proper-http-routes
Browse files Browse the repository at this point in the history
[HTTP] Call controller actions using URL from _publicApi instead of _query endpoint
  • Loading branch information
Shiranuit authored Apr 27, 2022
2 parents 5e76d11 + aeedba3 commit bb77cd5
Show file tree
Hide file tree
Showing 23 changed files with 584 additions and 84 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ You can then find the jars file in build/libs/
| **< 1.2.4** | **1.5.2** | **6.1** | **JDK-8** |
| **>= 1.2.4** | **1.6.8** | **7.4** | **JDK-11** |

| SDK Version | Kuzzle Version |
| :----------: | :------------: |
| **< 1.2.4** | **2.x.x** |
| **>= 1.2.4** | **Websocket: 2.x.x**<br>**HTTP: >=2.18.1** |

### Maven

```xml
Expand Down
59 changes: 31 additions & 28 deletions doc/1/core-classes/kuzzle/query/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,15 @@ public CompletableFuture<Response> query(

<br/>

| Argument | Type | Description |
| --------- | ----------------- | ---------------------- |
| `query` | <pre>Map<String, Object> | API request |
| Argument | Type | Description |
| -------- | ------------------------ | ----------- |
| `query` | <pre>Map<String, Object> | API request |

<SinceBadge version="1.2.3"/>

| Argument | Type | Description |
| --------- | ----------------- | ---------------------- |
| `query` | <pre>Map<String, Object><br>or String<br>or RawJson<br>or RequestPayload<br>or Object</pre> | API request |
| Argument | Type | Description |
| -------- | ------------------------------------------------------------------------------------------- | ----------- |
| `query` | <pre>Map<String, Object><br>or String<br>or RawJson<br>or RequestPayload<br>or Object</pre> | API request |

::: info
Calling query with a `String` or `RawJson` makes no differences, and will be interpreted as raw json strings.
Expand All @@ -74,15 +74,17 @@ This will avoid the deserialization + reserialization slowdown
All properties necessary for the Kuzzle API can be added in the query object.
The following properties are the most common.

| Property | Type | Description |
| ------------ | ----------------- | ---------------------------------------- |
| `controller` | <pre>String</pre> | Controller name (mandatory) |
| `action` | <pre>String</pre> | Action name (mandatory) |
| Property | Type | Description |
| ------------ | --------------------------------------------------------- | ---------------------------------------- |
| `controller` | <pre>String</pre> | Controller name (mandatory) |
| `action` | <pre>String</pre> | Action name (mandatory) |
| `body` | <pre>Map<String, Object><br>or RawJson<br>or Object</pre> | Query body for this action |
| `index` | <pre>String</pre> | Index name for this action |
| `collection` | <pre>String</pre> | Collection name for this action |
| `_id` | <pre>String</pre> | id for this action |
| `index` | <pre>String</pre> | Index name for this action |
| `collection` | <pre>String</pre> | Collection name for this action |
| `_id` | <pre>String</pre> | id for this action |
| `volatile` | <pre>Map<String, Object><br>or RawJson<br>or Object</pre> | Additional information to send to Kuzzle |
| `headers` | <pre>Map<String, Object></pre> | Optionnal headers to send (HTTP Only) |


## Returns

Expand Down Expand Up @@ -112,15 +114,15 @@ fun query(query: Any): CompletableFuture<Response>

<br/>

| Argument | Type | Description |
| --------- | ----------------- | ---------------------- |
| `query` | <pre>Map<String?, Any?> | API request |
| Argument | Type | Description |
| -------- | ----------------------- | ----------- |
| `query` | <pre>Map<String?, Any?> | API request |

<SinceBadge version="1.2.3"/>

| Argument | Type | Description |
| --------- | ----------------- | ---------------------- |
| `query` | <pre>Map<String?, Any?><br>or RawJson<br>or String<br>or RequestPayload<br>or Any</pre> | API request |
| Argument | Type | Description |
| -------- | --------------------------------------------------------------------------------------- | ----------- |
| `query` | <pre>Map<String?, Any?><br>or RawJson<br>or String<br>or RequestPayload<br>or Any</pre> | API request |

::: info
Calling query with a `String` or `RawJson` makes no differences, and will be interpreted as raw json strings.
Expand All @@ -140,15 +142,16 @@ This will avoid the deserialization + reserialization slowdown
All properties necessary for the Kuzzle API can be added in the query object.
The following properties are the most common.

| Property | Type | Description |
| ------------ | ----------------- | ---------------------------------------- |
| `controller` | <pre>String</pre> | Controller name (mandatory) |
| `action` | <pre>String</pre> | Action name (mandatory) |
| `body` | <pre>Map<String, Object><br>or RawJson<br>or Any</pre> | Query body for this action |
| `index` | <pre>String</pre> | Index name for this action |
| `collection` | <pre>String</pre> | Collection name for this action |
| `_id` | <pre>String</pre> | id for this action |
| `volatile` | <pre>Map<String, Object><br>or RawJson<br>or Any</pre> | Additional information to send to Kuzzle |
| Property | Type | Description |
| ------------ | ---------------------------------------------------- | ---------------------------------------- |
| `controller` | <pre>String</pre> | Controller name (mandatory) |
| `action` | <pre>String</pre> | Action name (mandatory) |
| `body` | <pre>Map<String, Any?><br>or RawJson<br>or Any</pre> | Query body for this action |
| `index` | <pre>String</pre> | Index name for this action |
| `collection` | <pre>String</pre> | Collection name for this action |
| `_id` | <pre>String</pre> | id for this action |
| `volatile` | <pre>Map<String, Any?><br>or RawJson<br>or Any</pre> | Additional information to send to Kuzzle |
| `headers` | <pre>Map<String, Any?></pre> | Optionnal headers to send (HTTP Only) |

## Returns

Expand Down
33 changes: 17 additions & 16 deletions doc/1/core-classes/response/introduction/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,20 @@ order: 0

## Properties

| Property | Type | Description |
|--- |--- |--- |
| `action` | <pre>String</pre> | Executed Kuzzle API controller's action |
| `collection` | <pre>String</pre> | Impacted collection |
| `controller` | <pre>String</pre> | Executed Kuzzle API controller |
| `error` | <pre>[ErrorResponse](/sdk/jvm/1/core-classes/error-response)</pre> | Error object (null if the request finished successfully) |
| `index` | <pre>String</pre> | Impacted index |
| `protocol` | <pre>String</pre> | Network protocol at the origin of the real-time notification |
| `requestId` | <pre>String</pre> | Request unique identifier |
| `result` | <pre>Object</pre> | Response payload (depends on the executed API action) |
| `room` | <pre>String</pre> | Room identifier (realtime only) |
| `scope` | <pre>String</pre> | Document scope ("in" or "out", realtime only) |
| `state` | <pre>String</pre> | Document state (realtime only) |
| `status` | <pre>int</pre> | Response status, following HTTP status codes |
| `timestamp` | <pre>Long</pre> | Notification timestamp (UTC) |
| `volatile` | <pre>Map<String, Object></pre> | Volatile data |
| Property | Type | Description |
| ------------ | ------------------------------------------------------------------ | ------------------------------------------------------------ |
| `action` | <pre>String</pre> | Executed Kuzzle API controller's action |
| `collection` | <pre>String</pre> | Impacted collection |
| `controller` | <pre>String</pre> | Executed Kuzzle API controller |
| `error` | <pre>[ErrorResponse](/sdk/jvm/1/core-classes/error-response)</pre> | Error object (null if the request finished successfully) |
| `headers` | <pre>Map<String, Object></pre> | Headers returned in the response |
| `index` | <pre>String</pre> | Impacted index |
| `protocol` | <pre>String</pre> | Network protocol at the origin of the real-time notification |
| `requestId` | <pre>String</pre> | Request unique identifier |
| `result` | <pre>Object</pre> | Response payload (depends on the executed API action) |
| `room` | <pre>String</pre> | Room identifier (realtime only) |
| `scope` | <pre>String</pre> | Document scope ("in" or "out", realtime only) |
| `state` | <pre>String</pre> | Document state (realtime only) |
| `status` | <pre>int</pre> | Response status, following HTTP status codes |
| `timestamp` | <pre>Long</pre> | Notification timestamp (UTC) |
| `volatile` | <pre>Map<String, Object></pre> | Volatile data |
28 changes: 21 additions & 7 deletions src/main/kotlin/io/kuzzle/sdk/Kuzzle.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import io.kuzzle.sdk.controllers.RealtimeController
import io.kuzzle.sdk.controllers.ServerController
import io.kuzzle.sdk.coreClasses.RequestPayload
import io.kuzzle.sdk.coreClasses.exceptions.ApiErrorException
import io.kuzzle.sdk.coreClasses.exceptions.InvalidJSON
import io.kuzzle.sdk.coreClasses.exceptions.KuzzleExceptionCode
import io.kuzzle.sdk.coreClasses.exceptions.NotConnectedException
import io.kuzzle.sdk.coreClasses.json.JsonSerializer
Expand Down Expand Up @@ -50,22 +51,34 @@ open class Kuzzle {
collectionController = CollectionController(this)
bulkController = BulkController(this)
// @TODO Create enums for events
protocol.addListener<MessageReceivedEvent>(::onMessageReceived)
protocol.addListener<NetworkStateChangeEvent>(::onNetworkStateChange)
protocol.addListener<RequestErrorEvent>(::onRequestError)
protocol.addListener(::onMessageReceived)
protocol.addListener(::onNetworkStateChange)
protocol.addListener(::onRequestError)
}

private fun onRequestError(event: RequestErrorEvent) {
if (event.requestId != null && queries[event.requestId] != null) {
queries[event.requestId]?.completeExceptionally(event.exception)
queries.remove(event.requestId)
if (event.requestId != null && queries[event.requestId!!] != null) {
queries[event.requestId!!]?.completeExceptionally(event.exception)
queries.remove(event.requestId!!)
}
}

private fun onMessageReceived(event: MessageReceivedEvent) {
val message = event.message
val jsonObject: Map<String?, Any?>
try {
jsonObject = JsonSerializer.deserialize(message) as Map<String?, Any?>
} catch (e: Exception) {
if (event.requestId != null) {
queries[event.requestId]?.completeExceptionally(InvalidJSON(event.message ?: "null"))
queries.remove(event.requestId)
} else {
protocol.trigger(UnhandledResponseEvent(message))
}
return
}
val response = Response().apply {
fromMap(JsonSerializer.deserialize(message) as Map<String?, Any?>)
fromMap(jsonObject)
}

val requestId = event.requestId ?: response.room ?: response.requestId
Expand All @@ -90,6 +103,7 @@ open class Kuzzle {
}

queries[requestId]?.completeExceptionally(ApiErrorException(response))
queries.remove(requestId)
protocol.trigger(TokenExpiredEvent())
}

Expand Down
6 changes: 5 additions & 1 deletion src/main/kotlin/io/kuzzle/sdk/controllers/AuthController.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import io.kuzzle.sdk.coreClasses.lang.Lang
import io.kuzzle.sdk.coreClasses.maps.KuzzleMap
import io.kuzzle.sdk.coreClasses.responses.Response
import io.kuzzle.sdk.events.LoginAttemptEvent
import io.kuzzle.sdk.events.LogoutAttemptEvent
import java.util.concurrent.CompletableFuture

class AuthController(kuzzle: Kuzzle) : BaseController(kuzzle) {
Expand Down Expand Up @@ -164,7 +165,10 @@ class AuthController(kuzzle: Kuzzle) : BaseController(kuzzle) {
put("controller", "auth")
put("action", "logout")
}
return kuzzle.query(query)
return kuzzle.query(query).thenApplyAsync { response ->
kuzzle.protocol.trigger(LogoutAttemptEvent())
response
}
}

@JvmOverloads
Expand Down
7 changes: 6 additions & 1 deletion src/main/kotlin/io/kuzzle/sdk/coreClasses/RequestPayload.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ data class RequestPayload(
var volatile: Any? = null,
var body: Any? = null,
var requestId: String? = null,
var other: Map<String?, Any?>? = null
var other: Map<String?, Any?>? = null,
var headers: Map<String?, Any?>? = null,
) {
fun toMap(): Map<String?, Any?> {
val map = HashMap<String?, Any?>()
Expand Down Expand Up @@ -64,6 +65,10 @@ data class RequestPayload(
map["requestId"] = requestId
}

if (headers != null) {
map["headers"] = headers
}

if (other != null) {
map.putAll(other!!)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ class ApiErrorException : KuzzleException {
constructor(response: Response) :
super(response.error?.message, response.status) {
if (response.error != null) {
this.stack = response.error?.stack
this.id = response.error?.id
this.stack = response.error!!.stack
this.id = response.error!!.id
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package io.kuzzle.sdk.coreClasses.exceptions

class InvalidJSON(json: String) : KuzzleException("Invalid JSON \"$json\".", 0)
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
package io.kuzzle.sdk.coreClasses.exceptions

enum class KuzzleExceptionCode {
MISSING_REQUESTID(0, "Missing field requestId"), MISSING_QUERY(400, "You must provide a query"), NOT_CONNECTED(500, "Not connected."), CONNECTION_LOST(500, "Connection lost"), WRONG_VOLATILE_TYPE(
MISSING_REQUESTID(0, "Missing field requestId"),
MISSING_CONTROLLER(0, "Missing field controller"),
MISSING_ACTION(0, "Missing field action"),
MISSING_QUERY(400, "You must provide a query"),
NOT_CONNECTED(500, "Not connected."),
CONNECTION_LOST(500, "Connection lost"),
WRONG_VOLATILE_TYPE(
400,
"Volatile data must be a Map<String, Object>"
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package io.kuzzle.sdk.coreClasses.exceptions

open class MissingActionException : KuzzleException(KuzzleExceptionCode.MISSING_ACTION)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package io.kuzzle.sdk.coreClasses.exceptions

open class MissingControllerException : KuzzleException(KuzzleExceptionCode.MISSING_CONTROLLER)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package io.kuzzle.sdk.coreClasses.exceptions

/**
* Thrown when attempting to interact with the network while not connected.
*/
class MissingURLParamException(templateParam: String, baseURL: String) : KuzzleException("Missing URL Param $templateParam in $baseURL", 0)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package io.kuzzle.sdk.coreClasses.exceptions

class URLNotFoundException(controller: String, action: String) : KuzzleException("No URL found for \"$controller:$action\".", 400)
10 changes: 10 additions & 0 deletions src/main/kotlin/io/kuzzle/sdk/coreClasses/http/HttpRequest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package io.kuzzle.sdk.coreClasses.http

import io.kuzzle.sdk.coreClasses.maps.KuzzleMap

data class HttpRequest(
val verb: String,
val url: String,
val body: KuzzleMap?,
val headers: KuzzleMap,
)
Loading

0 comments on commit bb77cd5

Please sign in to comment.