-
-
Notifications
You must be signed in to change notification settings - Fork 444
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'transactions-platform' of https://github.com/getsentry/…
…sentry-java into transactions-platform
- Loading branch information
Showing
20 changed files
with
384 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
public final class io/sentry/android/okhttp/BuildConfig { | ||
public static final field BUILD_TYPE Ljava/lang/String; | ||
public static final field DEBUG Z | ||
public static final field LIBRARY_PACKAGE_NAME Ljava/lang/String; | ||
public static final field VERSION_NAME Ljava/lang/String; | ||
public fun <init> ()V | ||
} | ||
|
||
public final class io/sentry/android/okhttp/SentryOkHttpInterceptor : okhttp3/Interceptor { | ||
public fun <init> ()V | ||
public fun <init> (Lio/sentry/IHub;)V | ||
public synthetic fun <init> (Lio/sentry/IHub;ILkotlin/jvm/internal/DefaultConstructorMarker;)V | ||
public fun intercept (Lokhttp3/Interceptor$Chain;)Lokhttp3/Response; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import io.gitlab.arturbosch.detekt.Detekt | ||
import io.gitlab.arturbosch.detekt.extensions.DetektExtension | ||
import org.jetbrains.kotlin.config.KotlinCompilerVersion | ||
|
||
plugins { | ||
id("com.android.library") | ||
kotlin("android") | ||
jacoco | ||
id(Config.QualityPlugins.gradleVersions) | ||
id(Config.QualityPlugins.detektPlugin) | ||
} | ||
|
||
android { | ||
compileSdkVersion(Config.Android.compileSdkVersion) | ||
|
||
defaultConfig { | ||
targetSdkVersion(Config.Android.targetSdkVersion) | ||
minSdkVersion(Config.Android.minSdkVersionOkHttp) | ||
|
||
versionName = project.version.toString() | ||
versionCode = project.properties[Config.Sentry.buildVersionCodeProp].toString().toInt() | ||
|
||
// for AGP 4.1 | ||
buildConfigField("String", "VERSION_NAME", "\"$versionName\"") | ||
} | ||
|
||
buildTypes { | ||
getByName("debug") | ||
getByName("release") { | ||
consumerProguardFiles("proguard-rules.pro") | ||
} | ||
} | ||
|
||
compileOptions { | ||
sourceCompatibility = JavaVersion.VERSION_1_8 | ||
targetCompatibility = JavaVersion.VERSION_1_8 | ||
} | ||
|
||
kotlinOptions { | ||
jvmTarget = JavaVersion.VERSION_1_8.toString() | ||
} | ||
|
||
testOptions { | ||
animationsDisabled = true | ||
unitTests.apply { | ||
isReturnDefaultValues = true | ||
isIncludeAndroidResources = true | ||
} | ||
} | ||
|
||
lintOptions { | ||
isWarningsAsErrors = true | ||
isCheckDependencies = true | ||
|
||
// We run a full lint analysis as build part in CI, so skip vital checks for assemble tasks. | ||
isCheckReleaseBuilds = false | ||
} | ||
} | ||
|
||
tasks.withType<Test> { | ||
configure<JacocoTaskExtension> { | ||
isIncludeNoLocationClasses = false | ||
} | ||
} | ||
|
||
kotlin { | ||
explicitApi() | ||
} | ||
|
||
dependencies { | ||
api(project(":sentry")) | ||
|
||
implementation(Config.Libs.okhttpBom) | ||
implementation(Config.Libs.okhttp) | ||
|
||
implementation(kotlin(Config.kotlinStdLib, KotlinCompilerVersion.VERSION)) | ||
|
||
// tests | ||
testImplementation(Config.TestLibs.kotlinTestJunit) | ||
testImplementation(Config.TestLibs.androidxJunit) | ||
testImplementation(Config.TestLibs.mockitoKotlin) | ||
testImplementation(Config.TestLibs.mockitoInline) | ||
testImplementation(Config.TestLibs.mockWebserver) | ||
} | ||
|
||
tasks.withType<Detekt> { | ||
// Target version of the generated JVM bytecode. It is used for type resolution. | ||
jvmTarget = JavaVersion.VERSION_1_8.toString() | ||
} | ||
|
||
configure<DetektExtension> { | ||
failFast = true | ||
buildUponDefaultConfig = true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
##---------------Begin: proguard configuration for OkHttp ---------- | ||
|
||
-keep class io.sentry.android.okhttp.** { *; } | ||
|
||
# To ensure that stack traces is unambiguous | ||
# https://developer.android.com/studio/build/shrink-code#decode-stack-trace | ||
-keepattributes LineNumberTable,SourceFile | ||
|
||
# https://square.github.io/okhttp/r8_proguard/ | ||
# JSR 305 annotations are for embedding nullability information. | ||
-dontwarn javax.annotation.** | ||
|
||
# A resource is loaded with a relative path so the package of this class must be preserved. | ||
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase | ||
|
||
# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java. | ||
-dontwarn org.codehaus.mojo.animal_sniffer.* | ||
|
||
# OkHttp platform used only on JVM and when Conscrypt dependency is available. | ||
-dontwarn okhttp3.internal.platform.ConscryptPlatform | ||
-dontwarn org.conscrypt.ConscryptHostnameVerifier | ||
|
||
##---------------End: proguard configuration for OkHttp ---------- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<manifest package="io.sentry.android.okhttp" /> |
56 changes: 56 additions & 0 deletions
56
sentry-android-okhttp/src/main/java/io/sentry/android/okhttp/SentryOkHttpInterceptor.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package io.sentry.android.okhttp | ||
|
||
import io.sentry.Breadcrumb | ||
import io.sentry.HubAdapter | ||
import io.sentry.IHub | ||
import io.sentry.SpanStatus | ||
import java.io.IOException | ||
import okhttp3.Interceptor | ||
import okhttp3.Response | ||
|
||
class SentryOkHttpInterceptor( | ||
private val hub: IHub = HubAdapter.getInstance() | ||
) : Interceptor { | ||
|
||
override fun intercept(chain: Interceptor.Chain): Response { | ||
var request = chain.request() | ||
|
||
val url = request.url.toString() | ||
val method = request.method | ||
|
||
// read transaction from the bound scope | ||
val span = hub.span?.startChild("http.client", "$method $url") | ||
|
||
var response: Response? = null | ||
|
||
var code: Int? = null | ||
try { | ||
span?.toSentryTrace()?.let { | ||
request = request.newBuilder().addHeader(it.name, it.value).build() | ||
} | ||
response = chain.proceed(request) | ||
code = response.code | ||
return response | ||
} catch (e: IOException) { | ||
span?.throwable = e | ||
throw e | ||
} finally { | ||
span?.finish(SpanStatus.fromHttpStatusCode(code, SpanStatus.INTERNAL_ERROR)) | ||
|
||
val breadcrumb = Breadcrumb.http(request.url.toString(), request.method, code) | ||
request.body?.contentLength().ifHasValidLength { | ||
breadcrumb.setData("requestBodySize", it) | ||
} | ||
response?.body?.contentLength().ifHasValidLength { | ||
breadcrumb.setData("responseBodySize", it) | ||
} | ||
hub.addBreadcrumb(breadcrumb) | ||
} | ||
} | ||
|
||
private fun Long?.ifHasValidLength(fn: (Long) -> Unit) { | ||
if (this != null && this != -1L) { | ||
fn.invoke(this) | ||
} | ||
} | ||
} |
118 changes: 118 additions & 0 deletions
118
sentry-android-okhttp/src/test/java/io/sentry/android/okhttp/SentryOkHttpInterceptorTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
package io.sentry.android.okhttp | ||
|
||
import com.nhaarman.mockitokotlin2.any | ||
import com.nhaarman.mockitokotlin2.check | ||
import com.nhaarman.mockitokotlin2.mock | ||
import com.nhaarman.mockitokotlin2.verify | ||
import com.nhaarman.mockitokotlin2.whenever | ||
import io.sentry.Breadcrumb | ||
import io.sentry.IHub | ||
import io.sentry.SentryTraceHeader | ||
import io.sentry.SentryTracer | ||
import io.sentry.SpanStatus | ||
import io.sentry.TransactionContext | ||
import java.io.IOException | ||
import kotlin.test.Test | ||
import kotlin.test.assertEquals | ||
import kotlin.test.assertNotNull | ||
import kotlin.test.assertNull | ||
import kotlin.test.fail | ||
import okhttp3.Interceptor | ||
import okhttp3.MediaType.Companion.toMediaType | ||
import okhttp3.OkHttpClient | ||
import okhttp3.Request | ||
import okhttp3.RequestBody.Companion.toRequestBody | ||
import okhttp3.mockwebserver.MockResponse | ||
import okhttp3.mockwebserver.MockWebServer | ||
|
||
class SentryOkHttpInterceptorTest { | ||
|
||
class Fixture { | ||
val hub = mock<IHub>() | ||
val interceptor = SentryOkHttpInterceptor(hub) | ||
val server = MockWebServer() | ||
val sentryTracer = SentryTracer(TransactionContext("name", "op"), hub) | ||
|
||
fun getSut(isSpanActive: Boolean = true, httpStatusCode: Int = 201, responseBody: String = "success"): OkHttpClient { | ||
if (isSpanActive) { | ||
whenever(hub.span).thenReturn(sentryTracer) | ||
} | ||
server.enqueue(MockResponse().setBody(responseBody).setResponseCode(httpStatusCode)) | ||
server.start() | ||
return OkHttpClient.Builder().addInterceptor(interceptor).build() | ||
} | ||
} | ||
|
||
val fixture = Fixture() | ||
|
||
@Test | ||
fun `when there is an active span, adds sentry trace header to the request`() { | ||
val sut = fixture.getSut() | ||
sut.newCall(Request.Builder().get().url(fixture.server.url("/hello")).build()).execute() | ||
val recorderRequest = fixture.server.takeRequest() | ||
assertNotNull(recorderRequest.headers[SentryTraceHeader.SENTRY_TRACE_HEADER]) | ||
} | ||
|
||
@Test | ||
fun `when there is no active span, does not add sentry trace header to the request`() { | ||
val sut = fixture.getSut(isSpanActive = false) | ||
sut.newCall(Request.Builder().get().url(fixture.server.url("/hello")).build()).execute() | ||
val recorderRequest = fixture.server.takeRequest() | ||
assertNull(recorderRequest.headers[SentryTraceHeader.SENTRY_TRACE_HEADER]) | ||
} | ||
|
||
@Test | ||
fun `does not overwrite response body`() { | ||
val sut = fixture.getSut() | ||
val response = sut.newCall(Request.Builder().get().url(fixture.server.url("/hello")).build()).execute() | ||
assertEquals("success", response.body?.string()) | ||
} | ||
|
||
@Test | ||
fun `creates a span around the request`() { | ||
val sut = fixture.getSut() | ||
val url = fixture.server.url("/hello") | ||
sut.newCall(Request.Builder().get().url(url).build()).execute() | ||
assertEquals(1, fixture.sentryTracer.children.size) | ||
val httpClientSpan = fixture.sentryTracer.children.first() | ||
assertEquals("http.client", httpClientSpan.operation) | ||
assertEquals("GET $url", httpClientSpan.description) | ||
assertEquals(SpanStatus.OK, httpClientSpan.status) | ||
} | ||
|
||
@Test | ||
fun `maps http status code to SpanStatus`() { | ||
val sut = fixture.getSut(httpStatusCode = 400) | ||
val url = fixture.server.url("/hello") | ||
sut.newCall(Request.Builder().get().url(url).build()).execute() | ||
val httpClientSpan = fixture.sentryTracer.children.first() | ||
assertEquals(SpanStatus.INVALID_ARGUMENT, httpClientSpan.status) | ||
} | ||
|
||
@Test | ||
fun `adds breadcrumb when http calls succeeds`() { | ||
val sut = fixture.getSut(responseBody = "response body") | ||
sut.newCall(Request.Builder().post("request-body".toRequestBody("text/plain".toMediaType())).url(fixture.server.url("/hello")).build()).execute() | ||
verify(fixture.hub).addBreadcrumb(check<Breadcrumb> { | ||
assertEquals("http", it.type) | ||
assertEquals(13L, it.data["responseBodySize"]) | ||
assertEquals(12L, it.data["requestBodySize"]) | ||
}) | ||
} | ||
|
||
@Test | ||
fun `adds breadcrumb when http calls results in exception`() { | ||
val chain = mock<Interceptor.Chain>() | ||
whenever(chain.proceed(any())).thenThrow(IOException()) | ||
whenever(chain.request()).thenReturn(Request.Builder().get().url(fixture.server.url("/hello")).build()) | ||
|
||
try { | ||
fixture.interceptor.intercept(chain) | ||
fail() | ||
} catch (e: IOException) {} | ||
|
||
verify(fixture.hub).addBreadcrumb(check<Breadcrumb> { | ||
assertEquals("http", it.type) | ||
}) | ||
} | ||
} |
1 change: 1 addition & 0 deletions
1
sentry-android-okhttp/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
mock-maker-inline |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.