Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ApolloWebSocketHandler #5291

Merged
merged 1 commit into from
Oct 10, 2023
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
4 changes: 4 additions & 0 deletions libraries/apollo-api/api/apollo-api.api
Original file line number Diff line number Diff line change
Expand Up @@ -1314,6 +1314,10 @@ public final class com/apollographql/apollo3/exception/MissingValueException : c
public fun <init> ()V
}

public final class com/apollographql/apollo3/exception/NoDataException : com/apollographql/apollo3/exception/ApolloException {
public fun <init> (Ljava/lang/Throwable;)V
}

public final class com/apollographql/apollo3/exception/SubscriptionOperationException : com/apollographql/apollo3/exception/ApolloException {
public fun <init> (Ljava/lang/String;Ljava/lang/Object;)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/Object;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.apollographql.apollo3.api
import com.apollographql.apollo3.exception.ApolloException
import com.apollographql.apollo3.exception.ApolloGraphQLException
import com.apollographql.apollo3.exception.DefaultApolloException
import com.apollographql.apollo3.exception.NoDataException
import com.benasher44.uuid.Uuid
import kotlin.jvm.JvmField
import kotlin.jvm.JvmName
Expand Down Expand Up @@ -110,7 +111,9 @@ private constructor(
/**
* Return [data] if not null or throws [exception] else
*/
fun dataOrThrow(): D = data ?: throw exception!!
fun dataOrThrow(): D {
return data ?: throw NoDataException(cause = exception)
}

fun hasErrors(): Boolean = !errors.isNullOrEmpty()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ sealed class ApolloException(message: String? = null, cause: Throwable? = null)
*/
class DefaultApolloException(message: String? = null, cause: Throwable? = null): ApolloException(message, cause)

/**
* No data was found
*/
class NoDataException(cause: Throwable?): ApolloException("No data was found", cause)

/**
* A network error happened: socket closed, DNS issue, TLS problem, etc...
*
Expand Down
103 changes: 38 additions & 65 deletions libraries/apollo-execution/api/apollo-execution.api
Original file line number Diff line number Diff line change
@@ -1,67 +1,3 @@
public abstract interface class com/apollographql/apollo3/execution/ApolloWebsocketClientMessage : com/apollographql/apollo3/execution/ApolloWebsocketClientMessageResult {
}

public final class com/apollographql/apollo3/execution/ApolloWebsocketClientMessageParseError : com/apollographql/apollo3/execution/ApolloWebsocketClientMessageResult {
public final fun getMessage ()Ljava/lang/String;
}

public abstract interface class com/apollographql/apollo3/execution/ApolloWebsocketClientMessageResult {
}

public final class com/apollographql/apollo3/execution/ApolloWebsocketComplete : com/apollographql/apollo3/execution/ApolloWebsocketServerMessage {
public fun <init> (Ljava/lang/String;)V
public final fun getId ()Ljava/lang/String;
public fun serialize (Lokio/Sink;)V
}

public final class com/apollographql/apollo3/execution/ApolloWebsocketConnectionAck : com/apollographql/apollo3/execution/ApolloWebsocketServerMessage {
public static final field INSTANCE Lcom/apollographql/apollo3/execution/ApolloWebsocketConnectionAck;
public fun serialize (Lokio/Sink;)V
}

public final class com/apollographql/apollo3/execution/ApolloWebsocketConnectionError : com/apollographql/apollo3/execution/ApolloWebsocketServerMessage {
public fun <init> ()V
public fun serialize (Lokio/Sink;)V
}

public final class com/apollographql/apollo3/execution/ApolloWebsocketData : com/apollographql/apollo3/execution/ApolloWebsocketServerMessage {
public fun <init> (Ljava/lang/String;Lcom/apollographql/apollo3/execution/GraphQLResponse;)V
public final fun getId ()Ljava/lang/String;
public final fun getResponse ()Lcom/apollographql/apollo3/execution/GraphQLResponse;
public fun serialize (Lokio/Sink;)V
}

public final class com/apollographql/apollo3/execution/ApolloWebsocketError : com/apollographql/apollo3/execution/ApolloWebsocketServerMessage {
public fun <init> (Ljava/lang/String;Lcom/apollographql/apollo3/api/Error;)V
public final fun getError ()Lcom/apollographql/apollo3/api/Error;
public final fun getId ()Ljava/lang/String;
public fun serialize (Lokio/Sink;)V
}

public final class com/apollographql/apollo3/execution/ApolloWebsocketInit : com/apollographql/apollo3/execution/ApolloWebsocketClientMessage {
public fun <init> (Ljava/lang/Object;)V
public final fun getConnectionParams ()Ljava/lang/Object;
}

public abstract interface class com/apollographql/apollo3/execution/ApolloWebsocketServerMessage {
public abstract fun serialize (Lokio/Sink;)V
}

public final class com/apollographql/apollo3/execution/ApolloWebsocketStart : com/apollographql/apollo3/execution/ApolloWebsocketClientMessage {
public fun <init> (Ljava/lang/String;Lcom/apollographql/apollo3/execution/GraphQLRequest;)V
public final fun getId ()Ljava/lang/String;
public final fun getRequest ()Lcom/apollographql/apollo3/execution/GraphQLRequest;
}

public final class com/apollographql/apollo3/execution/ApolloWebsocketStop : com/apollographql/apollo3/execution/ApolloWebsocketClientMessage {
public fun <init> (Ljava/lang/String;)V
public final fun getId ()Ljava/lang/String;
}

public final class com/apollographql/apollo3/execution/ApolloWebsocketTerminate : com/apollographql/apollo3/execution/ApolloWebsocketClientMessage {
public static final field INSTANCE Lcom/apollographql/apollo3/execution/ApolloWebsocketTerminate;
}

public final class com/apollographql/apollo3/execution/ExecutableSchema {
public final fun execute (Lcom/apollographql/apollo3/execution/GraphQLRequest;Lcom/apollographql/apollo3/api/ExecutionContext;)Lcom/apollographql/apollo3/execution/GraphQLResponse;
public final fun executeSubscription (Lcom/apollographql/apollo3/execution/GraphQLRequest;Lcom/apollographql/apollo3/api/ExecutionContext;)Lkotlinx/coroutines/flow/Flow;
Expand Down Expand Up @@ -117,7 +53,6 @@ public final class com/apollographql/apollo3/execution/GraphQLRequestError : com
}

public final class com/apollographql/apollo3/execution/GraphQLRequestKt {
public static final fun parseApolloWebsocketClientMessage (Ljava/lang/String;)Lcom/apollographql/apollo3/execution/ApolloWebsocketClientMessageResult;
public static final fun parseGetGraphQLRequest (Ljava/lang/String;)Lcom/apollographql/apollo3/execution/GraphQLRequestResult;
public static final fun parsePostGraphQLRequest (Lokio/BufferedSource;)Lcom/apollographql/apollo3/execution/GraphQLRequestResult;
public static final fun toGraphQLRequest (Ljava/util/Map;)Lcom/apollographql/apollo3/execution/GraphQLRequestResult;
Expand Down Expand Up @@ -227,3 +162,41 @@ public final class com/apollographql/apollo3/execution/ThrowingResolver : com/ap
public fun typename (Ljava/lang/Object;)Ljava/lang/String;
}

public final class com/apollographql/apollo3/execution/WebSocketBinaryMessage : com/apollographql/apollo3/execution/WebSocketMessage {
public fun <init> ([B)V
public final fun getData ()[B
}

public abstract interface class com/apollographql/apollo3/execution/WebSocketHandler {
public abstract fun handleMessage (Lcom/apollographql/apollo3/execution/WebSocketMessage;)V
}

public abstract interface class com/apollographql/apollo3/execution/WebSocketMessage {
}

public final class com/apollographql/apollo3/execution/WebSocketTextMessage : com/apollographql/apollo3/execution/WebSocketMessage {
public fun <init> (Ljava/lang/String;)V
public final fun getData ()Ljava/lang/String;
}

public final class com/apollographql/apollo3/execution/websocket/ApolloWebSocketHandler : com/apollographql/apollo3/execution/WebSocketHandler {
public fun <init> (Lcom/apollographql/apollo3/execution/ExecutableSchema;Lkotlinx/coroutines/CoroutineScope;Lcom/apollographql/apollo3/api/ExecutionContext;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)V
public synthetic fun <init> (Lcom/apollographql/apollo3/execution/ExecutableSchema;Lkotlinx/coroutines/CoroutineScope;Lcom/apollographql/apollo3/api/ExecutionContext;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun close ()V
public fun handleMessage (Lcom/apollographql/apollo3/execution/WebSocketMessage;)V
}

public final class com/apollographql/apollo3/execution/websocket/ConnectionInitAck : com/apollographql/apollo3/execution/websocket/ConnectionInitResult {
public static final field INSTANCE Lcom/apollographql/apollo3/execution/websocket/ConnectionInitAck;
}

public final class com/apollographql/apollo3/execution/websocket/ConnectionInitError : com/apollographql/apollo3/execution/websocket/ConnectionInitResult {
public fun <init> ()V
public fun <init> (Lcom/apollographql/apollo3/api/Optional;)V
public synthetic fun <init> (Lcom/apollographql/apollo3/api/Optional;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun getPayload ()Lcom/apollographql/apollo3/api/Optional;
}

public abstract interface class com/apollographql/apollo3/execution/websocket/ConnectionInitResult {
}

Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ package com.apollographql.apollo3.execution

import com.apollographql.apollo3.annotations.ApolloInternal
import com.apollographql.apollo3.api.Error
import com.apollographql.apollo3.api.Optional
import com.apollographql.apollo3.api.http.internal.urlDecode
import com.apollographql.apollo3.api.json.BufferedSinkJsonWriter
import com.apollographql.apollo3.api.json.JsonWriter
import com.apollographql.apollo3.api.json.jsonReader
import com.apollographql.apollo3.api.json.readAny
import com.apollographql.apollo3.api.json.writeAny
import com.apollographql.apollo3.api.json.writeObject
import okio.Buffer
import okio.BufferedSink
Expand Down Expand Up @@ -182,31 +184,31 @@ fun String.parseGetGraphQLRequest(): GraphQLRequestResult {
return builder.build()
}

sealed interface ApolloWebsocketClientMessageResult
internal sealed interface ApolloWebsocketClientMessageResult

class ApolloWebsocketClientMessageParseError internal constructor(
internal class ApolloWebsocketClientMessageParseError internal constructor(
val message: String,
) : ApolloWebsocketClientMessageResult

sealed interface ApolloWebsocketClientMessage : ApolloWebsocketClientMessageResult
internal sealed interface ApolloWebsocketClientMessage : ApolloWebsocketClientMessageResult

class ApolloWebsocketInit(
internal class ApolloWebsocketInit(
val connectionParams: Any?,
) : ApolloWebsocketClientMessage

class ApolloWebsocketStart(
internal class ApolloWebsocketStart(
val id: String,
val request: GraphQLRequest,
) : ApolloWebsocketClientMessage

class ApolloWebsocketStop(
internal class ApolloWebsocketStop(
val id: String,
) : ApolloWebsocketClientMessage


object ApolloWebsocketTerminate : ApolloWebsocketClientMessage
internal object ApolloWebsocketTerminate : ApolloWebsocketClientMessage

sealed interface ApolloWebsocketServerMessage {
internal sealed interface ApolloWebsocketServerMessage {
fun serialize(sink: Sink)
}

Expand All @@ -222,19 +224,24 @@ private fun Sink.writeMessage(type: String, block: (JsonWriter.() -> Unit)? = nu
}
}

object ApolloWebsocketConnectionAck : ApolloWebsocketServerMessage {
internal object ApolloWebsocketConnectionAck : ApolloWebsocketServerMessage {
override fun serialize(sink: Sink) {
sink.writeMessage("connection_ack")
}
}

class ApolloWebsocketConnectionError : ApolloWebsocketServerMessage {
internal class ApolloWebsocketConnectionError(private val payload: Optional<Any?>) : ApolloWebsocketServerMessage {
override fun serialize(sink: Sink) {
sink.writeMessage("connection_error")
sink.writeMessage("connection_error") {
if (payload is Optional.Present<*>) {
name("payload")
writeAny(payload.value)
}
}
}
}

class ApolloWebsocketData(
internal class ApolloWebsocketData(
val id: String,
val response: GraphQLResponse,
) : ApolloWebsocketServerMessage {
Expand All @@ -248,7 +255,7 @@ class ApolloWebsocketData(
}
}

class ApolloWebsocketError(
internal class ApolloWebsocketError(
val id: String?,
val error: Error,
) : ApolloWebsocketServerMessage {
Expand All @@ -264,7 +271,7 @@ class ApolloWebsocketError(
}
}

class ApolloWebsocketComplete(
internal class ApolloWebsocketComplete(
val id: String,
) : ApolloWebsocketServerMessage {
override fun serialize(sink: Sink) {
Expand All @@ -276,7 +283,7 @@ class ApolloWebsocketComplete(
}

@OptIn(ApolloInternal::class)
fun String.parseApolloWebsocketClientMessage(): ApolloWebsocketClientMessageResult {
internal fun String.parseApolloWebsocketClientMessage(): ApolloWebsocketClientMessageResult {
val map = try {
Buffer().writeUtf8(this).jsonReader().readAny() as Map<String, Any?>
} catch (e: Exception) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.apollographql.apollo3.execution

sealed interface WebSocketMessage
class WebSocketTextMessage(val data: String): WebSocketMessage
class WebSocketBinaryMessage(val data: ByteArray): WebSocketMessage

interface WebSocketHandler {
fun handleMessage(message: WebSocketMessage)
}
Loading