Commit 6719e010 authored by MozLando's avatar MozLando
Browse files

Merge #6875

6875: Remove service-glean's hard-dependency on httpurlconnection r=Dexterp37 a=badboy

Remove service-glean's hard-dependency on httpurlconnection

We still test with it, so we keep it around.

*BREAKING CHANGE*:

Users will need to supply a configuration with a ping uploader to Glean
now.
A default lib-fetch-httpurlconnection implementation can be used like
this:

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

val config = Configuration(httpClient = ConceptFetchHttpUploader(lazy { HttpURLConnectionClient() }))
Glean.initialize(context, true, config)
```

For Java this becomes:

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

ConceptFetchHttpUploader httpClient = ConceptFetchHttpUploader.fromClient(new HttpURLConnectionClient());
Configuration config = new Configuration(httpClient);
Glean.INSTANCE.initialize(context, true, config);
```

Fixes #6660 (at least partly)

I'm not familiar enough with service-experiments, so @travis79

 would need to take a look.

cc @pocmo for visibility.
Co-authored-by: default avatarJan-Erik Rediger <janerik@fnordig.de>
parents 956bc5f9 5bb9171f
......@@ -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
......@@ -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`.
......
......@@ -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
......@@ -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
......
......@@ -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,
......
......@@ -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 {
......
......@@ -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
......@@ -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`.
*/
@JvmStatic
fun fromClient(client: Client): ConceptFetchHttpUploader {
return ConceptFetchHttpUploader(lazy { client })
}
}
/**
......
......@@ -16,7 +16,9 @@ import org.robolectric.RobolectricTestRunner;
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 {
......@@ -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);
}
......
......@@ -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)
......
......@@ -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
......@@ -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())
......
......@@ -30,6 +30,7 @@ android {
dependencies {
implementation project(':lib-crash')
implementation project(':lib-fetch-httpurlconnection')
implementation project(':service-glean')
implementation project(':support-base')
......
......@@ -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() {
......@@ -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 {
......
......@@ -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
......
......@@ -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
......@@ -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
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment