Migrating the Android client from v4
This page takes an app from any 4.x release of the Android client to 5.3.0. For a fresh integration, use the Android guide instead.
5.3.0 speaks frame version 2 and needs a v5 relay. A v4 client cannot talk to a v5 relay (the relay answers 478), and 5.3.0 cannot talk to a v4 relay. Plan the app release alongside the relay upgrade.
Dependency and packages
The artifact was renamed, and the MTE core now arrives transitively:
// build.gradle.kts
dependencies {
// was: implementation("com.eclypses:eclypses-aws-mte-relay-client-android-release:4.x")
implementation("com.eclypses:mte-relay-client-android:5.3.0")
implementation("com.squareup.okhttp3:okhttp:4.12.0")
// Volley, slf4j and logback no longer need declaring for the relay
}
The package moved from com.eclypses.mte.relay to com.eclypses.relay:
import com.eclypses.relay.Relay // was: com.eclypses.mte.relay.Relay
import com.eclypses.relay.RelayResponseListener // was: com.eclypses.mte.relay.callback.RelayResponseListener
Remove any keep rules you added for the relay. 5.3.0 ships its own consumer R8 rules, including the MTE core's; a minified release build needs nothing from you.
Getting the instance
// v4 — a pairing callback at construction
val relay = Relay.getInstance(context, object : RelayResponseListener {
override fun onCompletion(success: Boolean, message: String) { }
})
// 5.3.0 — no listener; pairing happens on the first request
val relay = Relay.getInstance(applicationContext)
The licence is built in. getInstance throws RelayException if it cannot be validated.
headersToEncrypt is now unencryptedHeaders, and means the opposite
v4 encrypted only the headers you listed. 5.3.0 encrypts every header and leaves in the
clear only those you list. Porting a v4 list unchanged would send exactly the headers you meant
to protect in the clear, so in most cases pass null. List a header only when something
between your app and the relay has to read it. Never list Authorization.
Content-Type, Content-Length, Host, X-MTE-Relay-Route and X-MTE-Relay-Client are
reserved and always encrypted; listing one throws IllegalArgumentException.
Requests: Volley is gone
addToMteRequestQueue and RelayVolleyRequestListener were removed; OkHttp is the only
transport. If your app uses OkHttp, the smallest change is interceptor mode. Your client,
calls and callbacks stay as they are:
val client = OkHttpClient.Builder()
.addInterceptor(Relay.getInstance(applicationContext).getOkHttpInterceptor())
.build()
client.newCall(request).enqueue(yourExistingCallback) // request addressed to the relay host
A failure of the relay's own arrives at your onFailure as a RelayCallException whose
cause is the specific exception.
Or send through the relay directly (wrapper mode, also required for file transfer and SSE):
relay.send(request, null, null, object : RelayOkHttpRequestListener {
override fun onResponse(response: Response) { } // 2xx
override fun onError(response: Response) { } // the origin replied non-2xx
override fun onFailure(request: Request, cause: Throwable) { } // no HTTP response at all
})
Callbacks arrive on a background thread; Volley delivered them on the main thread, so post UI work there yourself.
File upload
The route moved into RelayFileRequestProperties, which also gained pathnamePrefix:
// v4
val props = RelayFileRequestProperties(serverUrl, headers, headersToEncrypt, streamCallback)
relay.uploadFile(props, route, responseListener, progressCallback)
// 5.3.0
val props = RelayFileRequestProperties(
serverUrl, // the relay host
route, // e.g. "/api/files/upload"
null, // pathnamePrefix
headers, // must include Content-Length: the exact body size
null, // unencryptedHeaders — leave encrypted
streamCallback, // RelayStreamCallback: write the body, then close the stream
)
relay.uploadFile(props, responseListener, progressCallback)
The relay's advertised request-body limit now applies to streamed uploads too. An upload over
it is refused before anything is sent, with RelayRequestTooLargeException.
File download
// v4
val props = RelayFileRequestProperties(serverUrl, route, downloadPath, headers, headersToEncrypt)
// 5.3.0 — note the order: downloadPath comes BEFORE pathnamePrefix
val props = RelayFileRequestProperties(
serverUrl,
route,
downloadFile.absolutePath, // downloadPath
null, // pathnamePrefix
headers,
null, // unencryptedHeaders
)
relay.downloadFile(props, responseListener)
Both new constructors take a String in the third and fourth positions, so swapping them
compiles and fails at runtime with a 404. Keep the order above.
Re-pairing and settings
// v4
relay.rePairWithRelayServer(relayUrl, listener)
relay.adjustRelaySettings(serverUrl, streamChunkSize, pairPoolSize, persistPairs)
// 5.3.0
relay.rePairWithRelayServer("https://your-relay-server.com", null,
object : RelayResponseListener {
override fun onCompletion(success: Boolean, message: String) { }
})
val settings = RelayClientSettings(5, 8, 15, 300, 1.0)
// minPairs, basePairs, maxPairs, keepAliveIntervalSeconds, acquisitionWaitTime
relay.adjustRelaySettings("https://your-relay-server.com", null, settings,
object : RelayResponseListener {
override fun onCompletion(success: Boolean, message: String) { }
})
The stream chunk size and persistPairs are gone.
Logging
The static logging methods no longer take a server URL:
Relay.enableFileLogging(true) // was: enableFileLogging(serverUrl, true)
val log = Relay.readLogFile() // was: readLogFile(serverUrl)
Relay.clearLogFile()
A healthy start logs Using Relay Version 5.3.0 and Mte Version 4.2.1.