Skip to content

Commit bd7d56b

Browse files
committed
Implement backend discovery.
The mechanism is the following: Each android libary that provides a backend needs to implement a `BackendFactory` and register it in its manifest. Runtime will discover it via manifest and create the backend via the factory, providing `CreationContext` to it.
1 parent 1491e06 commit bd7d56b

26 files changed

+528
-91
lines changed

transport/transport-backend-cct/src/main/AndroidManifest.xml

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,18 @@
1414

1515
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
1616
package="com.google.android.datatransport.backend.cct">
17-
<!--Although the *SdkVersion is captured in gradle build files, this is required for non gradle builds-->
18-
<!--<uses-sdk android:minSdkVersion="14"/>-->
17+
<!--Although the *SdkVersion is captured in gradle build files, this is required for non gradle builds-->
18+
<!--<uses-sdk android:minSdkVersion="14"/>-->
1919

20-
<uses-permission android:name="android.permission.INTERNET" />
20+
<uses-permission android:name="android.permission.INTERNET" />
21+
22+
<application>
23+
<service
24+
android:name="com.google.android.datatransport.runtime.backends.TransportBackendDiscovery"
25+
android:exported="false">
26+
<meta-data
27+
android:name="backend:com.google.android.datatransport.cct.CctBackendFactory"
28+
android:value="cct" />
29+
</service>
30+
</application>
2131
</manifest>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright 2018 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.android.datatransport.cct;
16+
17+
import android.support.annotation.Keep;
18+
import android.support.annotation.VisibleForTesting;
19+
import com.google.android.datatransport.runtime.backends.BackendFactory;
20+
import com.google.android.datatransport.runtime.backends.CreationContext;
21+
import com.google.android.datatransport.runtime.backends.TransportBackend;
22+
23+
@Keep
24+
public class CctBackendFactory implements BackendFactory {
25+
private static final String URL = mergeStrings("hts/pa.ogepscmlgbth", "tp:/lygolai.o/o/ac");
26+
27+
@Override
28+
public TransportBackend create(CreationContext creationContext) {
29+
return new CctTransportBackend(
30+
URL, creationContext.getWallClock(), creationContext.getMonotonicClock());
31+
}
32+
33+
@VisibleForTesting
34+
static String mergeStrings(String part1, String part2) {
35+
int sizeDiff = part1.length() - part2.length();
36+
if (sizeDiff < 0 || sizeDiff > 1) {
37+
throw new IllegalArgumentException("Invalid input received");
38+
}
39+
40+
StringBuilder url = new StringBuilder(part1.length() + part2.length());
41+
42+
for (int i = 0; i < part1.length(); i++) {
43+
url.append(part1.charAt(i));
44+
if (part2.length() > i) {
45+
url.append(part2.charAt(i));
46+
}
47+
}
48+
49+
return url.toString();
50+
}
51+
}
Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,19 @@
1515
package com.google.android.datatransport.cct;
1616

1717
import android.os.Build;
18-
import android.support.annotation.VisibleForTesting;
1918
import com.google.android.datatransport.cct.proto.AndroidClientInfo;
2019
import com.google.android.datatransport.cct.proto.BatchedLogRequest;
2120
import com.google.android.datatransport.cct.proto.ClientInfo;
2221
import com.google.android.datatransport.cct.proto.LogEvent;
2322
import com.google.android.datatransport.cct.proto.LogRequest;
2423
import com.google.android.datatransport.cct.proto.LogResponse;
2524
import com.google.android.datatransport.cct.proto.QosTierConfiguration;
26-
import com.google.android.datatransport.runtime.BackendRequest;
27-
import com.google.android.datatransport.runtime.BackendResponse;
28-
import com.google.android.datatransport.runtime.BackendResponse.Status;
2925
import com.google.android.datatransport.runtime.EventInternal;
30-
import com.google.android.datatransport.runtime.TransportBackend;
26+
import com.google.android.datatransport.runtime.backends.BackendRequest;
27+
import com.google.android.datatransport.runtime.backends.BackendResponse;
28+
import com.google.android.datatransport.runtime.backends.BackendResponse.Status;
29+
import com.google.android.datatransport.runtime.backends.TransportBackend;
3130
import com.google.android.datatransport.runtime.time.Clock;
32-
import com.google.android.datatransport.runtime.time.UptimeClock;
33-
import com.google.android.datatransport.runtime.time.WallTimeClock;
3431
import com.google.protobuf.ByteString;
3532
import com.google.protobuf.InvalidProtocolBufferException;
3633
import java.io.ByteArrayOutputStream;
@@ -50,9 +47,9 @@
5047
import java.util.logging.Logger;
5148
import java.util.zip.GZIPOutputStream;
5249

53-
public class GoogleTransportBackend implements TransportBackend {
50+
final class CctTransportBackend implements TransportBackend {
5451

55-
private static final Logger LOGGER = Logger.getLogger(GoogleTransportBackend.class.getName());
52+
private static final Logger LOGGER = Logger.getLogger(CctTransportBackend.class.getName());
5653
private static final int CONNECTION_TIME_OUT = 30000;
5754
private static final int READ_TIME_OUT = 40000;
5855
private static final String CONTENT_ENCODING_HEADER_KEY = "Content-Encoding";
@@ -80,17 +77,12 @@ private static URL parseUrlOrThrow(String url) {
8077
}
8178
}
8279

83-
@VisibleForTesting
84-
GoogleTransportBackend(String url, Clock wallTimeClock, Clock uptimeClock) {
80+
CctTransportBackend(String url, Clock wallTimeClock, Clock uptimeClock) {
8581
this.endPoint = parseUrlOrThrow(url);
8682
this.uptimeClock = uptimeClock;
8783
this.wallTimeClock = wallTimeClock;
8884
}
8985

90-
public GoogleTransportBackend() {
91-
this("https://play.googleapis.com/log/batch", new WallTimeClock(), new UptimeClock());
92-
}
93-
9486
@Override
9587
public EventInternal decorate(EventInternal eventInternal) {
9688
return eventInternal
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2018 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.android.datatransport.cct;
16+
17+
import static com.google.common.truth.Truth.assertThat;
18+
import static org.junit.Assert.assertThrows;
19+
20+
import org.junit.Test;
21+
import org.junit.runner.RunWith;
22+
import org.junit.runners.JUnit4;
23+
24+
@RunWith(JUnit4.class)
25+
public class CctBackendFactoryTest {
26+
@Test
27+
public void mergeStrings_whenPartsAreUnequalLength() {
28+
String part1 = "hts/eapecm";
29+
String part2 = "tp:/xml.o";
30+
assertThat(CctBackendFactory.mergeStrings(part1, part2)).isEqualTo("https://example.com");
31+
}
32+
33+
@Test
34+
public void mergeStrings_whenPartsAreEqualLength() {
35+
String part1 = "hts/eape.o";
36+
String part2 = "tp:/xmlscm";
37+
assertThat(CctBackendFactory.mergeStrings(part1, part2)).isEqualTo("https://examples.com");
38+
}
39+
40+
@Test
41+
public void mergeStrings_whenPart2IsLongerThanPart1() {
42+
String part1 = "135";
43+
String part2 = "2467";
44+
assertThrows(
45+
IllegalArgumentException.class, () -> CctBackendFactory.mergeStrings(part1, part2));
46+
}
47+
}
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,22 @@
2626
import com.github.tomakehurst.wiremock.junit.WireMockRule;
2727
import com.google.android.datatransport.Priority;
2828
import com.google.android.datatransport.cct.proto.LogResponse;
29-
import com.google.android.datatransport.runtime.BackendRequest;
30-
import com.google.android.datatransport.runtime.BackendResponse;
31-
import com.google.android.datatransport.runtime.BackendResponse.Status;
3229
import com.google.android.datatransport.runtime.EventInternal;
30+
import com.google.android.datatransport.runtime.backends.BackendRequest;
31+
import com.google.android.datatransport.runtime.backends.BackendResponse;
32+
import com.google.android.datatransport.runtime.backends.BackendResponse.Status;
3333
import java.util.Collections;
3434
import org.junit.Rule;
3535
import org.junit.Test;
3636
import org.junit.runner.RunWith;
3737
import org.robolectric.RobolectricTestRunner;
3838

3939
@RunWith(RobolectricTestRunner.class)
40-
public class GoogleTransportBackendTest {
40+
public class CctTransportBackendTest {
4141

4242
private static String TEST_ENDPOINT = "http://localhost:8999/api";
43-
private static GoogleTransportBackend BACKEND =
44-
new GoogleTransportBackend(TEST_ENDPOINT, () -> 3, () -> 1);
43+
private static CctTransportBackend BACKEND =
44+
new CctTransportBackend(TEST_ENDPOINT, () -> 3, () -> 1);
4545
private static String TRANSPORT_NAME = "3";
4646

4747
@Rule public WireMockRule wireMockRule = new WireMockRule(8999);

transport/transport-backend-cct/transport-backend-cct.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ dependencies {
7676
//Android compatible version of Apache httpclient.
7777
testImplementation 'org.apache.httpcomponents:httpclient-android:4.3.5.1'
7878
testImplementation 'org.robolectric:robolectric:4.2'
79+
testImplementation 'junit:junit:4.13-beta-2'
7980

8081
androidTestImplementation 'com.android.support.test:runner:1.0.2'
8182
implementation 'com.android.support:support-annotations:28.0.0'

transport/transport-runtime/gradle.properties

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
version=16.0.0
15+
version=16.0.0
16+
android.enableUnitTestBinaryResources=true

transport/transport-runtime/src/main/AndroidManifest.xml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@
1414

1515
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
1616
package="com.google.android.datatransport.runtime">
17-
<!--Although the *SdkVersion is captured in gradle build files, this is required for non gradle builds-->
18-
<!--<uses-sdk android:minSdkVersion="14"/>-->
17+
<!--Although the *SdkVersion is captured in gradle build files, this is required for non gradle builds-->
18+
<!--<uses-sdk android:minSdkVersion="14"/>-->
19+
20+
<application>
21+
<service
22+
android:name=".backends.TransportBackendDiscovery"
23+
android:exported="false" />
24+
</application>
1925
</manifest>

transport/transport-runtime/src/main/java/com/google/android/datatransport/runtime/BackendRegistry.java

Lines changed: 0 additions & 41 deletions
This file was deleted.

transport/transport-runtime/src/main/java/com/google/android/datatransport/runtime/TransportRuntime.java

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ public class TransportRuntime implements TransportInternal {
3939

4040
private static volatile TransportRuntimeComponent INSTANCE = null;
4141

42-
private final BackendRegistry backendRegistry;
4342
private final Clock eventClock;
4443
private final Clock uptimeClock;
4544
private final Scheduler scheduler;
@@ -48,13 +47,11 @@ public class TransportRuntime implements TransportInternal {
4847

4948
@Inject
5049
TransportRuntime(
51-
BackendRegistry backendRegistry,
5250
@WallTime Clock eventClock,
5351
@Monotonic Clock uptimeClock,
5452
Scheduler scheduler,
5553
SynchronizationGuard guard,
5654
Uploader uploader) {
57-
this.backendRegistry = backendRegistry;
5855
this.eventClock = eventClock;
5956
this.uptimeClock = uptimeClock;
6057
this.scheduler = scheduler;
@@ -92,11 +89,6 @@ public static TransportRuntime getInstance() {
9289
return localRef.getTransportRuntime();
9390
}
9491

95-
/** Register a {@link TransportBackend}. */
96-
public void register(String name, TransportBackend backend) {
97-
backendRegistry.register(name, backend);
98-
}
99-
10092
/** Returns a {@link TransportFactory} for a given {@code backendName}. */
10193
public TransportFactory newFactory(String backendName) {
10294
return new TransportFactoryImpl(backendName, this);

transport/transport-runtime/src/main/java/com/google/android/datatransport/runtime/TransportRuntimeModule.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import android.content.Context;
1818
import android.os.Build;
19+
import com.google.android.datatransport.runtime.backends.BackendRegistry;
1920
import com.google.android.datatransport.runtime.scheduling.ImmediateScheduler;
2021
import com.google.android.datatransport.runtime.scheduling.Scheduler;
2122
import com.google.android.datatransport.runtime.scheduling.jobscheduling.AlarmManagerScheduler;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2018 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.android.datatransport.runtime.backends;
16+
17+
/** Used by backend discovery to create {@link TransportBackend}s. */
18+
public interface BackendFactory {
19+
TransportBackend create(CreationContext creationContext);
20+
}

0 commit comments

Comments
 (0)