Skip to content
This repository has been archived by the owner on Nov 1, 2022. It is now read-only.

Remove service-glean's hard-dependency on httpurlconnection #6875

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@ import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.work.testing.WorkManagerTestInitHelper
import kotlinx.coroutines.runBlocking
import mozilla.components.concept.fetch.Client
import mozilla.components.lib.fetch.httpurlconnection.HttpURLConnectionClient
import mozilla.components.service.experiments.Configuration
import mozilla.components.service.experiments.Experiment
import mozilla.components.service.experiments.Experiments
import mozilla.components.service.experiments.ExperimentsSnapshot
import mozilla.components.service.experiments.ExperimentsUpdater
import mozilla.components.service.glean.Glean
import mozilla.components.service.glean.config.Configuration as GleanConfiguration
import mozilla.components.service.glean.net.ConceptFetchHttpUploader
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull
Expand All @@ -42,7 +46,9 @@ class ExperimentsDebugActivityTest {
fun setup() {
WorkManagerTestInitHelper.initializeTestWorkManager(context)

Glean.initialize(context, uploadEnabled = true)
val httpClient = ConceptFetchHttpUploader(lazy { HttpURLConnectionClient() as Client })
val config = GleanConfiguration(httpClient = httpClient)
Glean.initialize(context, uploadEnabled = true, configuration = config)

// This makes sure we have a "launch" intent in our package, otherwise
// it will fail looking for it in `GleanDebugActivityTest`.
Expand Down
6 changes: 4 additions & 2 deletions components/service/glean/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,11 @@ dependencies {

api GLEAN_LIBRARY

// So consumers can set a HTTP client.
api project(':concept-fetch')

implementation project(':support-ktx')
implementation project(':support-base')
implementation project(':concept-fetch')
implementation project(':lib-fetch-httpurlconnection')
implementation project(':support-utils')

testImplementation Dependencies.androidx_test_core
Expand All @@ -65,6 +66,7 @@ dependencies {
testImplementation Dependencies.androidx_work_testing

testImplementation project(':support-test')
testImplementation project(':lib-fetch-httpurlconnection')
testImplementation project(':lib-fetch-okhttp')

testImplementation GLEAN_LIBRARY_FORUNITTESTS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,11 @@ object Glean {
* @param uploadEnabled A [Boolean] that determines the initial state of the uploader
* @param configuration A Glean [Configuration] object with global settings.
*/
@JvmOverloads
@MainThread
fun initialize(
applicationContext: Context,
uploadEnabled: Boolean,
configuration: Configuration = Configuration()
configuration: Configuration
) {
GleanCore.initialize(
applicationContext = applicationContext,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,27 @@

package mozilla.components.service.glean.config

import mozilla.components.lib.fetch.httpurlconnection.HttpURLConnectionClient
import mozilla.components.service.glean.net.ConceptFetchHttpUploader
import mozilla.telemetry.glean.net.PingUploader
import mozilla.telemetry.glean.config.Configuration as GleanCoreConfiguration

/**
* The Configuration class describes how to configure the Glean.
*
* @property serverEndpoint the server pings are sent to. Please note that this is
* @property httpClient The HTTP client implementation to use for uploading pings.
* If you don't provide your own networking stack with an HTTP client to use,
* you can fall back to a simple implementation on top of `java.net` using
* `ConceptFetchHttpUploader(lazy { HttpURLConnectionClient() as Client })`
* @property serverEndpoint (optional) the server pings are sent to. Please note that this is
* is only meant to be changed for tests.
* @property channel the release channel the application is on, if known. This will be
* @property channel (optional )the release channel the application is on, if known. This will be
* sent along with all the pings, in the `client_info` section.
* @property maxEvents the number of events to store before the events ping is sent
* @property httpClient The HTTP client implementation to use for uploading pings.
* @property maxEvents (optional) the number of events to store before the events ping is sent
*/
data class Configuration @JvmOverloads constructor (
val httpClient: PingUploader,
val serverEndpoint: String = DEFAULT_TELEMETRY_ENDPOINT,
val channel: String? = null,
val maxEvents: Int? = null,
val httpClient: PingUploader = ConceptFetchHttpUploader(lazy { HttpURLConnectionClient() })
val maxEvents: Int? = null
) {
// The following is required to support calling our API from Java.
companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ import mozilla.components.concept.fetch.isClientError
import mozilla.components.concept.fetch.isSuccess
import mozilla.components.support.base.log.logger.Logger
import mozilla.telemetry.glean.net.HeadersList
import mozilla.telemetry.glean.net.PingUploader
import mozilla.telemetry.glean.net.PingUploader as CorePingUploader
import java.io.IOException
import java.util.concurrent.TimeUnit

typealias PingUploader = CorePingUploader

/**
* A simple ping Uploader, which implements a "send once" policy, never
* storing or attempting to send the ping again. This uses Android Component's
Expand All @@ -33,6 +35,16 @@ class ConceptFetchHttpUploader(
const val DEFAULT_CONNECTION_TIMEOUT = 10000L
// The timeout, in milliseconds, to use when reading from the server.
const val DEFAULT_READ_TIMEOUT = 30000L

/**
* Export a constructor that is usable from Java.
*
* This looses the lazyness of creating the `client`.
badboy marked this conversation as resolved.
Show resolved Hide resolved
*/
@JvmStatic
fun fromClient(client: Client): ConceptFetchHttpUploader {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Firefox Reality would need to use a different uploader. Do we need to do this for other uploaders as well? @pocmo

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I fully understand. The 1:1 migration for Firefox Reality would be to continue using HttpUrlConnectionClient (MozillaReality/FirefoxReality#3339)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Client is coming from concept-fetch.
So as long as whatever they want to use adheres to that they're fine.

return ConceptFetchHttpUploader(lazy { client })
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
import java.util.HashMap;
import java.util.Map;

import mozilla.components.lib.fetch.httpurlconnection.HttpURLConnectionClient;
import mozilla.components.service.glean.config.Configuration;
import mozilla.components.service.glean.net.ConceptFetchHttpUploader;

@RunWith(RobolectricTestRunner.class)
public class GleanFromJavaTest {
Expand All @@ -28,15 +30,18 @@ public class GleanFromJavaTest {
public void testInitGleanWithDefaults() {
Context context = ApplicationProvider.getApplicationContext();
WorkManagerTestInitHelper.initializeTestWorkManager(context);
Glean.INSTANCE.initialize(context, true);
ConceptFetchHttpUploader httpClient = ConceptFetchHttpUploader.fromClient(new HttpURLConnectionClient());
Configuration config = new Configuration(httpClient);
Glean.INSTANCE.initialize(context, true, config);
}

@Test
public void testInitGleanWithConfiguration() {
Context context = ApplicationProvider.getApplicationContext();
WorkManagerTestInitHelper.initializeTestWorkManager(context);
ConceptFetchHttpUploader httpClient = ConceptFetchHttpUploader.fromClient(new HttpURLConnectionClient());
Configuration config =
new Configuration(Configuration.DEFAULT_TELEMETRY_ENDPOINT, "test-channel");
new Configuration(httpClient, Configuration.DEFAULT_TELEMETRY_ENDPOINT, "test-channel");
Glean.INSTANCE.initialize(context, true, config);
}

Expand Down
7 changes: 7 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ permalink: /changelog/
* [Gecko](https://github.com/mozilla-mobile/android-components/blob/master/buildSrc/src/main/java/Gecko.kt)
* [Configuration](https://github.com/mozilla-mobile/android-components/blob/master/buildSrc/src/main/java/Config.kt)

* **service-glean**
* ⚠️ **This is a breaking change**: Glean's configuration now requires explicitly setting an http client. Users need to pass one at construction.
A default `lib-fetch-httpurlconnection` implementation is available.
Add it to the configuration object like this:
`val config = Configuration(httpClient = ConceptFetchHttpUploader(lazy { HttpURLConnectionClient() as Client }))`.
See [PR #6875](https://github.com/mozilla-mobile/android-components/pull/6875) for details and full code examples.

# 41.0.0

* [Commits](https://github.com/mozilla-mobile/android-components/compare/v40.0.0...v41.0.0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ package org.mozilla.samples.browser

import android.app.Application
import mozilla.components.browser.session.Session
import mozilla.components.concept.fetch.Client
import mozilla.components.feature.addons.update.GlobalAddonDependencyProvider
import mozilla.components.lib.fetch.httpurlconnection.HttpURLConnectionClient
import mozilla.components.service.glean.Glean
import mozilla.components.service.glean.config.Configuration
import mozilla.components.service.glean.net.ConceptFetchHttpUploader
import mozilla.components.support.base.facts.Facts
import mozilla.components.support.base.facts.processor.LogFactProcessor
import mozilla.components.support.base.log.Log
Expand All @@ -31,10 +35,12 @@ class SampleApplication : Application() {
return
}

val httpClient = ConceptFetchHttpUploader(lazy { HttpURLConnectionClient() as Client })
val config = Configuration(httpClient = httpClient)
// IMPORTANT: the following lines initialize the Glean SDK but disable upload
// of pings. If, for testing purposes, upload is required to be on, change the
// next line to `uploadEnabled = true`.
Glean.initialize(applicationContext, uploadEnabled = false)
Glean.initialize(applicationContext, uploadEnabled = false, configuration = config)

Facts.registerProcessor(LogFactProcessor())

Expand Down
1 change: 1 addition & 0 deletions samples/crash/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ android {

dependencies {
implementation project(':lib-crash')
implementation project(':lib-fetch-httpurlconnection')
implementation project(':service-glean')
implementation project(':support-base')

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,16 @@ import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import mozilla.components.support.base.log.Log
import mozilla.components.support.base.log.sink.AndroidLogSink
import mozilla.components.concept.fetch.Client
import mozilla.components.lib.crash.Crash
import mozilla.components.lib.crash.CrashReporter
import mozilla.components.lib.crash.service.CrashReporterService
import mozilla.components.lib.crash.service.GleanCrashReporterService
import mozilla.components.lib.fetch.httpurlconnection.HttpURLConnectionClient
import mozilla.components.service.glean.Glean
import mozilla.components.support.base.crash.Breadcrumb
import mozilla.components.service.glean.config.Configuration
import mozilla.components.service.glean.net.ConceptFetchHttpUploader
import java.util.UUID

class CrashApplication : Application() {
Expand Down Expand Up @@ -49,7 +53,9 @@ class CrashApplication : Application() {
).install(this)

// Initialize Glean for recording by the GleanCrashReporterService
Glean.initialize(applicationContext, uploadEnabled = true)
val httpClient = ConceptFetchHttpUploader(lazy { HttpURLConnectionClient() as Client })
val config = Configuration(httpClient = httpClient)
Glean.initialize(applicationContext, uploadEnabled = true, configuration = config)
}

companion object {
Expand Down
1 change: 1 addition & 0 deletions samples/glean/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ dependencies {
implementation project(':service-glean')
implementation project(':service-experiments')
implementation project(':support-base')
implementation project(':lib-fetch-httpurlconnection')

implementation Dependencies.kotlin_stdlib
implementation Dependencies.kotlin_coroutines
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ package org.mozilla.samples.glean

import android.app.Application
import android.content.Intent
import mozilla.components.concept.fetch.Client
import mozilla.components.lib.fetch.httpurlconnection.HttpURLConnectionClient
import mozilla.components.service.glean.Glean
import mozilla.components.service.glean.config.Configuration
import mozilla.components.service.glean.net.ConceptFetchHttpUploader
import mozilla.components.service.experiments.Experiments
import mozilla.components.support.base.log.Log
import mozilla.components.support.base.log.sink.AndroidLogSink
Expand All @@ -28,7 +32,9 @@ class GleanApplication : Application() {

// Initialize the Glean library. Ideally, this is the first thing that
// must be done right after enabling logging.
Glean.initialize(applicationContext, uploadEnabled = true)
val httpClient = ConceptFetchHttpUploader(lazy { HttpURLConnectionClient() as Client })
val config = Configuration(httpClient = httpClient)
Glean.initialize(applicationContext, uploadEnabled = true, configuration = config)

// Initialize the Experiments library and pass in the callback that will generate a
// broadcast Intent to signal the application that experiments have been updated. This is
Expand Down