Update Protobuf support (#2381)

Summary:
**Update protobuf library with new support for `enum` and `oneof` types**

## Changelog

- Update plugin code for library API changes and other cleanup
- Add instructions to readme

Pull Request resolved: https://github.com/facebook/flipper/pull/2381

Test Plan: see demo app at https://github.com/hbmartin/protobuf_java_to_protobufjs

Reviewed By: priteshrnandgaonkar

Differential Revision: D28831035

Pulled By: passy

fbshipit-source-id: 46e196293330b615394606bd3486ea47ad6a0630
This commit is contained in:
Harold Martin
2021-06-02 12:03:42 -07:00
committed by Facebook GitHub Bot
parent b7d7326bae
commit 62967314c1
7 changed files with 53 additions and 29 deletions

View File

@@ -25,7 +25,7 @@ android {
implementation project(':network-plugin') implementation project(':network-plugin')
implementation deps.protobuf implementation deps.protobuf
implementation "com.squareup.retrofit2:retrofit:2.9.0" implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation "com.github.hbmartin:protobuf_java_to_protobufjs:0.0.1" implementation "com.github.hbmartin:protobuf_java_to_protobufjs:0.1.0"
compileOnly deps.jsr305 compileOnly deps.jsr305
} }
} }

View File

@@ -9,24 +9,23 @@ package com.facebook.flipper.plugins.retrofit2protobuf
import com.facebook.flipper.android.AndroidFlipperClient import com.facebook.flipper.android.AndroidFlipperClient
import com.facebook.flipper.core.FlipperArray import com.facebook.flipper.core.FlipperArray
import com.facebook.flipper.core.FlipperObject
import com.facebook.flipper.core.FlipperValue import com.facebook.flipper.core.FlipperValue
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin import com.facebook.flipper.plugins.network.NetworkFlipperPlugin
import com.facebook.flipper.plugins.retrofit2protobuf.adapter.GenericCallDefinitionsToMessageDefinitionsIfProtobuf import com.facebook.flipper.plugins.retrofit2protobuf.adapter.GenericCallDefinitionsToMessageDefinitionsIfProtobuf
import com.facebook.flipper.plugins.retrofit2protobuf.adapter.RetrofitServiceToGenericCallDefinitions import com.facebook.flipper.plugins.retrofit2protobuf.adapter.RetrofitServiceToGenericCallDefinitions
import com.facebook.flipper.plugins.retrofit2protobuf.model.CallNestedMessagesPayload import com.facebook.flipper.plugins.retrofit2protobuf.model.CallNestedMessagesPayload
import me.haroldmartin.protobufjavatoprotobufjs.adapter.FullNamedMessagesToNestedMessages
object SendProtobufToFlipperFromRetrofit { object SendProtobufToFlipperFromRetrofit {
operator fun invoke(baseUrl: String, service: Class<*>) { operator fun invoke(baseUrl: String, service: Class<*>) {
AndroidFlipperClient.getInstanceIfInitialized()?.let { client -> getNetworkPlugin()?.addProtobufDefinitions(
(client.getPlugin(NetworkFlipperPlugin.ID) as? NetworkFlipperPlugin) baseUrl,
?.send( generateProtobufDefinitions(service).toFlipperArray()
"addProtobufDefinitions", )
FlipperObject.Builder().put( }
baseUrl, generateProtobufDefinitions(service).toFlipperArray()
).build() private fun getNetworkPlugin(): NetworkFlipperPlugin? {
) return AndroidFlipperClient.getInstanceIfInitialized()?.let { client ->
client.getPlugin(NetworkFlipperPlugin.ID) as? NetworkFlipperPlugin
} }
} }
@@ -39,9 +38,9 @@ object SendProtobufToFlipperFromRetrofit {
path = it.path, path = it.path,
method = it.method, method = it.method,
requestMessageFullName = it.requestMessageFullName, requestMessageFullName = it.requestMessageFullName,
requestDefinitions = FullNamedMessagesToNestedMessages(it.requestModel), requestDefinitions = it.requestModel,
responseMessageFullName = it.responseMessageFullName, responseMessageFullName = it.responseMessageFullName,
responseDefinitions = FullNamedMessagesToNestedMessages(it.responseModel) responseDefinitions = it.responseModel
) )
} }
} }

View File

@@ -25,9 +25,9 @@ internal object GenericCallDefinitionsToMessageDefinitionsIfProtobuf {
path = definition.path, path = definition.path,
method = definition.method, method = definition.method,
responseMessageFullName = responseRootAndMessages?.rootFullName, responseMessageFullName = responseRootAndMessages?.rootFullName,
responseModel = responseRootAndMessages?.messages, responseModel = responseRootAndMessages?.descriptors,
requestMessageFullName = requestRootAndMessages?.rootFullName, requestMessageFullName = requestRootAndMessages?.rootFullName,
requestModel = requestRootAndMessages?.messages requestModel = requestRootAndMessages?.descriptors
) )
} }
} }

View File

@@ -53,8 +53,8 @@ private val Array<Annotation>.urlPathAndMethod: Pair<String, String>?
private val Method.requestBodyType: Class<*>? private val Method.requestBodyType: Class<*>?
get() { get() {
parameterAnnotations.forEachIndexed { index, parameters -> parameterAnnotations.forEachIndexed { index, annotations ->
parameters.forEach { annotation -> annotations.forEach { annotation ->
if (annotation.annotationClass == retrofit2.http.Body::class) { if (annotation.annotationClass == retrofit2.http.Body::class) {
return parameterTypes[index] return parameterTypes[index]
} }

View File

@@ -7,6 +7,7 @@
package com.facebook.flipper.plugins.retrofit2protobuf.model package com.facebook.flipper.plugins.retrofit2protobuf.model
import com.facebook.flipper.core.FlipperArray
import com.facebook.flipper.core.FlipperObject import com.facebook.flipper.core.FlipperObject
import com.facebook.flipper.core.FlipperValue import com.facebook.flipper.core.FlipperValue
@@ -14,29 +15,34 @@ internal data class CallNestedMessagesPayload(
val path: String, val path: String,
val method: String, val method: String,
val requestMessageFullName: String?, val requestMessageFullName: String?,
val requestDefinitions: Map<String, Any>, val requestDefinitions: Map<String, Any>?,
val responseMessageFullName: String?, val responseMessageFullName: String?,
val responseDefinitions: Map<String, Any> val responseDefinitions: Map<String, Any>?
) : FlipperValue { ) : FlipperValue {
override fun toFlipperObject(): FlipperObject { override fun toFlipperObject(): FlipperObject {
return FlipperObject.Builder() return FlipperObject.Builder()
.put("path", path) .put("path", path)
.put("method", method) .put("method", method)
.put("requestMessageFullName", requestMessageFullName) .put("requestMessageFullName", requestMessageFullName)
.put("requestDefinitions", requestDefinitions.toFlipperObject()) .put("requestDefinitions", requestDefinitions?.toFlipperObject())
.put("responseMessageFullName", responseMessageFullName) .put("responseMessageFullName", responseMessageFullName)
.put("responseDefinitions", responseDefinitions.toFlipperObject()) .put("responseDefinitions", responseDefinitions?.toFlipperObject())
.build() .build()
} }
} }
private fun Map<*, *>.toFlipperObject(): FlipperObject { private fun Map<*, *>.toFlipperObject(): FlipperObject {
val builder = FlipperObject.Builder() val builder = FlipperObject.Builder()
this.forEach { this.forEach { (key, value) ->
builder.put( val castValue = when (value) {
it.key as String, is Map<*, *> -> value.toFlipperObject()
if (it.value is Map<*, *>) (it.value as Map<*, *>).toFlipperObject() else it.value is Iterable<*> -> value.toFlipperArray()
) else -> value
}
builder.put(key as String, castValue)
} }
return builder.build() return builder.build()
} }
private fun Iterable<*>.toFlipperArray(): FlipperArray =
fold(FlipperArray.Builder()) { builder, value -> builder.put(value as? String) }.build()

View File

@@ -7,13 +7,13 @@
package com.facebook.flipper.plugins.retrofit2protobuf.model package com.facebook.flipper.plugins.retrofit2protobuf.model
import me.haroldmartin.protobufjavatoprotobufjs.model.FullNamedMessages import me.haroldmartin.protobufjavatoprotobufjs.adapter.JsDescriptors
internal data class FullNamedMessagesCallDefinition( internal data class FullNamedMessagesCallDefinition(
val path: String, val path: String,
val method: String, val method: String,
val requestMessageFullName: String?, val requestMessageFullName: String?,
val responseMessageFullName: String?, val responseMessageFullName: String?,
val responseModel: FullNamedMessages?, val responseModel: JsDescriptors?,
val requestModel: FullNamedMessages? val requestModel: JsDescriptors?
) )

View File

@@ -49,6 +49,25 @@ new OkHttpClient.Builder()
As interceptors can modify the request and response, add the Flipper interceptor after all others to get an accurate view of the network traffic. As interceptors can modify the request and response, add the Flipper interceptor after all others to get an accurate view of the network traffic.
### Protobuf / Retrofit Integration
If you are using Retrofit with Protobuf request or response types, you can setup automatic decoding so that the network inspector can display a human readable payload. First you must add the separate dependency:
```groovy
dependencies {
debugImplementation 'com.facebook.flipper:flipper-retrofit2-protobuf-plugin:0.91.2'
}
```
Then call `SendProtobufToFlipperFromRetrofit` for each service class.
```kotlin
import com.facebook.flipper.plugins.retrofit2protobuf.SendProtobufToFlipperFromRetrofit
SendProtobufToFlipperFromRetrofit("https://baseurl.com/", MyApiService::class.java)
```
## iOS ## iOS
To enable network inspection, add the following pod to your Podfile: To enable network inspection, add the following pod to your Podfile: