Skip to content

Commit

Permalink
updated protoc; refactor ConnectState; added .setAccessTokenHeader() …
Browse files Browse the repository at this point in the history
…function with callback
  • Loading branch information
yurizhuk committed Aug 4, 2024
1 parent c9110a7 commit 45a3169
Show file tree
Hide file tree
Showing 12 changed files with 135 additions and 65 deletions.
2 changes: 1 addition & 1 deletion mobile-sdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ afterEvaluate {

groupId = "com.webitel"
artifactId = "mobile-sdk"
version = "0.13.1"
version = "0.14.1"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ internal class AuthRepository(
}


fun setAccessTokenHeader(token: String) {
authApi.setAccessTokenHeader(token)
fun setAccessTokenHeader(token: String, callback: CallbackListener<Unit>?) {
authApi.setAccessTokenHeader(token, callback)
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ internal interface AuthApi: BaseApi {
fun logout(callback: CallbackListener<Unit>)
fun inspect(callback: CallbackListener<UserSession>)
fun setSession(auth: String, callback: CallbackListener<UserSession>)
fun setAccessTokenHeader(auth: String)
fun setAccessTokenHeader(auth: String, callback: CallbackListener<Unit>?)
fun registerFcm(token: String, callback: CallbackListener<RegisterResult>)
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ import webitel.chat.MessageOuterClass
import webitel.portal.Account.Identity
import webitel.portal.Auth
import webitel.portal.Auth.TokenRequest
import webitel.portal.Connect
import webitel.portal.Connect.Echo
import webitel.portal.Connect.Request
import webitel.portal.Connect.Response
import webitel.portal.Connect.Update
import webitel.portal.Connect.UpdateDisconnect
import webitel.portal.CustomerGrpc
import webitel.portal.CustomerOuterClass
import webitel.portal.CustomerOuterClass.RegisterDeviceResponse
Expand Down Expand Up @@ -68,7 +68,7 @@ internal class ClientGrpc(
Handler(thread.looper)
}

private var connectState = ConnectState.DISCONNECTED
private var connectState: ConnectState = ConnectState.None


init {
Expand Down Expand Up @@ -149,32 +149,42 @@ internal class ClientGrpc(
}


override fun setAccessTokenHeader(auth: String) {
override fun setAccessTokenHeader(auth: String, callback: CallbackListener<Unit>?) {
make {
setAccessToken(auth)
updateConnect()
}
}


private fun updateConnect() {
if (requestObserver != null) {
try {
resetBackoff()
val stub = CustomerGrpc.newStub(channel.channel)
val m = CustomerOuterClass.InspectRequest
.newBuilder()
.build()

stub.inspect(m, object : StreamObserver<Auth.AccessToken> {
override fun onNext(value: Auth.AccessToken?) {}
override fun onError(t: Throwable) {
logger.error("setAccessTokenHeader", "${t.message}")
if (requestObserver != null) {
try {
resetBackoff()
val stub = CustomerGrpc.newStub(channel.channel)
val m = CustomerOuterClass.InspectRequest
.newBuilder()
.build()

stub.inspect(m, object : StreamObserver<Auth.AccessToken> {
override fun onNext(value: Auth.AccessToken?) {
logger.debug("token", "token updated in headers and stream")
callback?.onSuccess(Unit)
}
override fun onError(t: Throwable) {
logger.error("token", "token not updated in stream. ${t.message}")
callback?.let {
val err = parseError(t)
it.onError(err)
}
}
override fun onCompleted() {}
})
} catch (e: Exception) {
logger.error("token", "token not updated in stream. ${e.message}")
callback?.let {
val err = parseError(e)
it.onError(err)
}
override fun onCompleted() {}
})
} catch (e: Exception) {
logger.error("setAccessTokenHeader", "${e.message}")
}

}else {
logger.debug("token", "token updated in headers")
callback?.onSuccess(Unit)
}
}
}
Expand Down Expand Up @@ -257,8 +267,8 @@ internal class ClientGrpc(
.newBuilder()
.build()

stub.logout(m, object : StreamObserver<Connect.UpdateSignedOut> {
override fun onNext(value: Connect.UpdateSignedOut?) {
stub.logout(m, object : StreamObserver<UpdateDisconnect> {
override fun onNext(value: UpdateDisconnect?) {
callback.onSuccess(Unit)
}

Expand Down Expand Up @@ -490,18 +500,11 @@ internal class ClientGrpc(
}


@Synchronized
private fun stopStream() {
make {
val s = requestObserver
requestObserver = null
try {
s?.onCompleted()
} catch (_: Exception) {
}
timer?.cancel()
timer = null
}
requestObserver?.onCompleted()
requestObserver = null
timer?.cancel()
timer = null
}


Expand Down Expand Up @@ -658,6 +661,7 @@ internal class ClientGrpc(
private fun openBiDirectionalConnect() {
try {
resetBackoff()
logger.debug("connect", "create new connection...")
val stub = CustomerGrpc.newStub(channel.channel)
requestObserver?.onCompleted()
requestObserver = stub.connect(object : StreamObserver<Update> {
Expand Down Expand Up @@ -719,6 +723,10 @@ internal class ClientGrpc(
message?.let {
chatListener?.onNewMessage(it)
}

} else if (update.data.`is`(UpdateDisconnect::class.java)) {
logger.debug("UpdateDisconnect", "Server closes connection...")

} else {
logger.debug("notImplementedEvent", update.toString())
}
Expand Down Expand Up @@ -778,26 +786,31 @@ internal class ClientGrpc(

override fun onStart(methodName: String) {
if (methodName != CustomerGrpc.getConnectMethod().bareMethodName) return
logger.debug("onStateChanged", "from = $connectState, to = ${ConnectState.CONNECTING}")
connectionListeners.onStateChanged(from = connectState, to = ConnectState.CONNECTING)
connectState = ConnectState.CONNECTING
logger.debug("onStateChanged", "from = $connectState, to = ${ConnectState.Connecting}")
connectionListeners.onStateChanged(from = connectState, to = ConnectState.Connecting)
connectState = ConnectState.Connecting
}


override fun onReady(methodName: String) {
if (methodName != CustomerGrpc.getConnectMethod().bareMethodName) return
logger.debug("onStateChanged", "from = $connectState, to = ${ConnectState.READY}")
connectionListeners.onStateChanged(from = connectState, to = ConnectState.READY)
connectState = ConnectState.READY
logger.debug("onStateChanged", "from = $connectState, to = ${ConnectState.Ready}")
connectionListeners.onStateChanged(from = connectState, to = ConnectState.Ready)
connectState = ConnectState.Ready
}


override fun onClose(methodName: String, status: Status?, trailers: Metadata?) {
if (methodName != CustomerGrpc.getConnectMethod().bareMethodName) return
ConnectState.DISCONNECTED.message = status.toString()
logger.debug("onStateChanged", "from = $connectState, to = ${ConnectState.DISCONNECTED}")
connectionListeners.onStateChanged(from = connectState, to = ConnectState.DISCONNECTED)
connectState = ConnectState.DISCONNECTED
val statusCode = Code.forNumber(status?.code?.value() ?: 2)
val reason = Error(
message = status?.description ?: status.toString(),
code = statusCode
)
val state = ConnectState.Disconnected(reason)
logger.debug("onStateChanged", "from = ${connectState}, to = $state")
connectionListeners.onStateChanged(from = connectState, to = state)
connectState = state
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.webitel.mobile_sdk.data.grps

import com.webitel.mobile_sdk.data.portal.WebitelPortalClient
import io.grpc.CallOptions
import io.grpc.Channel
import io.grpc.ClientCall
Expand Down Expand Up @@ -32,11 +33,23 @@ internal class GrpcInterceptor(
return object : ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(next.newCall(method, callOptions)) {
override fun sendMessage(message: ReqT) {
super.sendMessage(message)
WebitelPortalClient.logger.debug(
"intercept",
"Method: ${method?.bareMethodName ?: "undefined bareMethodName"}, Message: ${message.toString()}"
)
}



override fun start(responseListener: Listener<RespT>?, headers: Metadata?) {
setupHeaders(headers, method?.bareMethodName ?: "undefined bareMethodName")
listener?.onStart(method?.bareMethodName.toString())

WebitelPortalClient.logger.debug(
"connect.start",
"${method?.bareMethodName.toString()} - ${headers.toString()}"
)

super.start(object : ForwardingClientCallListener.SimpleForwardingClientCallListener<RespT>(responseListener) {
override fun onMessage(message: RespT) {
super.onMessage(message)
Expand All @@ -48,8 +61,8 @@ internal class GrpcInterceptor(
}

override fun onClose(status: Status?, trailers: Metadata?) {
listener?.onClose(method?.bareMethodName.toString(), status, trailers)
super.onClose(status, trailers)
listener?.onClose(method?.bareMethodName.toString(), status, trailers)
}
}, headers)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package com.webitel.mobile_sdk.data.portal
import android.util.Log
import com.webitel.mobile_sdk.domain.LogLevel

internal class WLogger(private val level: LogLevel) {

internal class WLogger {
var level: LogLevel = LogLevel.ERROR
fun info(tag: String, message: String) {
if (level <= LogLevel.INFO) {
Log.i(tag, message)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,18 @@ internal class WebitelPortalClient(
private val voice: VoiceClient

private var userSession: UserSession? = null
private val logger: WLogger

companion object {
val logger: WLogger = WLogger()
}


init {
val session: () -> UserSession? = {
userSession
}

logger = WLogger(client.logLevel)
logger.level = client.logLevel

grpc = ClientGrpc(
getChannelConfig(),
Expand Down Expand Up @@ -163,7 +166,12 @@ internal class WebitelPortalClient(


override fun setAccessTokenHeader(token: String) {
authRepository.setAccessTokenHeader(token)
authRepository.setAccessTokenHeader(token, null)
}


override fun setAccessTokenHeader(token: String, callback: CallbackListener<Unit>) {
authRepository.setAccessTokenHeader(token, callback)
}


Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,24 @@
package com.webitel.mobile_sdk.domain


enum class ConnectState(var message: String = "") { CONNECTING, READY, DISCONNECTED }
sealed class ConnectState {
/**
* The initial state, indicating no connection attempt has been made yet.
*/
object None : ConnectState()

/**
* The state when a connection attempt is currently in progress.
*/
object Connecting : ConnectState()

/**
* The state indicating that the connection is successfully established and ready for use.
*/
object Ready : ConnectState()

/**
* The state indicating that the connection has been disconnected, with an associated error describing the reason for disconnection.
*/
data class Disconnected(val reason: Error) : ConnectState()
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ interface Dialog {
* @param request request to send a file.
* @param callback receive result from server onSent(Message)/onError.
*
* * @return Transfer control: .pause()/.resume()/.cancel()
* @return A CancellationToken that can be used to cancel the sending operation.
*/
fun sendFile(request: FileTransferRequest, callback: MessageCallbackListener): CancellationToken

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,19 @@ interface PortalClient {
*/
fun setAccessTokenHeader(token: String)

/**
* Sets the access token.
*
* This function stores the provided access token and calls the callback upon completion of the operation.
*
* @param token The access token to be set.
* @param callback called when the operation is finished, where:
*
* `.onSuccess`: If the token was successfully set.
* `.onError`: If an error occurred while setting the token, along with an `Error` object describing the error.
*/
fun setAccessTokenHeader(token: String, callback: CallbackListener<Unit>)

/**
* Register device PUSH subscription
* */
Expand Down
11 changes: 7 additions & 4 deletions mobile-sdk/src/main/proto/portal/connect.proto
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,13 @@ message Response {
google.rpc.Status err = 2;
}

message UpdateSignedOut {
google.rpc.Status cause = 1;
}

message Echo {
bytes data = 1;
}

// UpdateDisconnect notifies the client about
// an imminent disconnect due to specified reason.
message UpdateDisconnect {
// The disconnect reason
google.rpc.Status cause = 1;
}
2 changes: 1 addition & 1 deletion mobile-sdk/src/main/proto/portal/customer.proto
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ service Customer {
rpc Token(TokenRequest) returns (AccessToken);

// Logout session request
rpc Logout(LogoutRequest) returns (UpdateSignedOut);
rpc Logout(LogoutRequest) returns (UpdateDisconnect);

// Inspect your authorization access token
rpc Inspect(InspectRequest) returns (AccessToken);
Expand Down

0 comments on commit 45a3169

Please sign in to comment.