From c6597efb1a040577082f48a762524c645e320429 Mon Sep 17 00:00:00 2001 From: ekoby <7406535+ekoby@users.noreply.github.com> Date: Thu, 27 May 2021 08:41:47 -0400 Subject: [PATCH] get API version prefix and re-write following request URLs (#193) --- .../kotlin/org/openziti/api/Controller.kt | 28 ++++++++++++++----- .../src/main/kotlin/org/openziti/api/types.kt | 11 +++++++- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/ziti/src/main/kotlin/org/openziti/api/Controller.kt b/ziti/src/main/kotlin/org/openziti/api/Controller.kt index d72b069e..747d6c93 100644 --- a/ziti/src/main/kotlin/org/openziti/api/Controller.kt +++ b/ziti/src/main/kotlin/org/openziti/api/Controller.kt @@ -23,9 +23,7 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.asFlow import kotlinx.coroutines.flow.emitAll import kotlinx.coroutines.flow.flow -import okhttp3.Interceptor -import okhttp3.OkHttpClient -import okhttp3.ResponseBody +import okhttp3.* import okhttp3.logging.HttpLoggingInterceptor import org.openziti.Errors import org.openziti.ZitiException @@ -125,6 +123,7 @@ internal class Controller(endpoint: URL, sslContext: SSLContext, trustManager: X fun delete(@Header("zt-session") session: String, @Path("p", encoded = true) path: String): Call> } + internal var apiPrefix: String = "" internal val api: API internal var apiSession: ApiSession? = null @@ -138,16 +137,17 @@ internal class Controller(endpoint: URL, sslContext: SSLContext, trustManager: X } val clt: OkHttpClient + val retrofit: Retrofit init { clt = OkHttpClient.Builder().apply { socketFactory(AsychChannelSocket.Factory()) sslSocketFactory(AsyncTLSSocketFactory(sslContext), trustManager) cache(null) - addInterceptor(SessionInterceptor()) + addInterceptor(ZitiInterceptor()) addInterceptor(loggingInterceptor) }.build() - val retrofit = Retrofit.Builder() + retrofit = Retrofit.Builder() .baseUrl(endpoint) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(CoroutineCallAdapterFactory()) @@ -157,7 +157,14 @@ internal class Controller(endpoint: URL, sslContext: SSLContext, trustManager: X errorConverter = retrofit.responseBodyConverter(Response::class.java, emptyArray()) } - suspend fun version() = api.version().await().data + suspend fun version(): ControllerVersion { + val ver = api.version().await().data!! + i { "controller[${retrofit.baseUrl()}] version(${ver.version}/${ver.revision})"} + val prefix = ver.apiVersions.run { get("edge-client") ?: get("edge") }?.get("v1")?.path + + prefix?.let { apiPrefix = it } ?: w {"did not receive expected apiVersions mapping"} + return ver + } internal suspend fun currentApiSession(): ApiSession = api.currentApiSession().runCatching { await().data!! }.getOrElse { convertError(it) } @@ -169,6 +176,8 @@ internal class Controller(endpoint: URL, sslContext: SSLContext, trustManager: X } if (apiSession == null) { + runCatching { version() }.getOrElse { convertError(it) } + val call = if (login == null) api.authenticateCert(getClientInfo()) else api.authenticate(login) @@ -321,7 +330,7 @@ internal class Controller(endpoint: URL, sslContext: SSLContext, trustManager: X else resp.message() } - inner class SessionInterceptor : Interceptor { + inner class ZitiInterceptor : Interceptor { override fun intercept(chain: Interceptor.Chain): okhttp3.Response { val origReq = chain.request() val rb = origReq.newBuilder() @@ -329,6 +338,11 @@ internal class Controller(endpoint: URL, sslContext: SSLContext, trustManager: X rb.header("Accept", "application/json") } apiSession?.let { rb.header("zt-session", it.token) } + val newPath = "${apiPrefix}${origReq.url().encodedPath()}" + val newUrl = origReq.url().newBuilder() + .encodedPath(newPath) + .build() + rb.url(newUrl) val req = rb.build() d("${req.method()} ${req.url()} session=${apiSession?.id} t[${Thread.currentThread().name}]") diff --git a/ziti/src/main/kotlin/org/openziti/api/types.kt b/ziti/src/main/kotlin/org/openziti/api/types.kt index 3e4ee040..449ef1e1 100644 --- a/ziti/src/main/kotlin/org/openziti/api/types.kt +++ b/ziti/src/main/kotlin/org/openziti/api/types.kt @@ -60,7 +60,16 @@ abstract class ApiObject(val _links: Map? = null) internal class SessionReq(val serviceId: String, val type: SessionType = SessionType.Dial) -data class ControllerVersion(val buildDate: String, val revision: String, val runtimeVersion: String, val version: String) +internal data class ApiVersion (val path: String) + +internal data class ControllerVersion( + val buildDate: String, + val revision: String, + val runtimeVersion: String, + val version: String, + val apiVersions: Map> +) + internal class Login(val username: String, val password: String) internal class ApiSession( val id: String,