@Override public void write(JSONStringer writer) throws JSONException { /* Override abstract log JSON since it's Common Schema and not App Center schema. */ /* Part A. */ writer.key(VER).value(getVer()); writer.key(NAME).value(getName()); writer.key(TIME).value(JSONDateUtils.toString(getTimestamp())); JSONUtils.write(writer, POP_SAMPLE, getPopSample()); JSONUtils.write(writer, IKEY, getIKey()); JSONUtils.write(writer, FLAGS, getFlags()); JSONUtils.write(writer, CV, getCV()); /* Part A extensions. */ if (getExt() != null) { writer.key(EXT).object(); getExt().write(writer); writer.endObject(); } /* Parts B & C. */ if (getData() != null) { writer.key(DATA).object(); getData().write(writer); writer.endObject(); } }
dest.setVer("3.0"); dest.setTimestamp(src.getTimestamp()); dest.setIKey("o" + COMMON_SCHEMA_PREFIX_SEPARATOR + getTargetKey(transmissionTarget)); dest.addTransmissionTarget(transmissionTarget); if (dest.getExt() == null) { dest.setExt(new Extensions()); dest.getExt().setProtocol(new ProtocolExtension()); dest.getExt().getProtocol().setDevModel(device.getModel()); dest.getExt().getProtocol().setDevMake(device.getOemName()); dest.getExt().setUser(new UserExtension()); dest.getExt().getUser().setLocalId(UserIdContext.getPrefixedUserId(src.getUserId())); dest.getExt().getUser().setLocale(device.getLocale().replace("_", "-")); dest.getExt().setOs(new OsExtension()); dest.getExt().getOs().setName(device.getOsName()); dest.getExt().getOs().setVer(device.getOsVersion() + "-" + device.getOsBuild() + "-" + device.getOsApiLevel()); dest.getExt().setApp(new AppExtension()); dest.getExt().getApp().setVer(device.getAppVersion()); dest.getExt().getApp().setId("a" + COMMON_SCHEMA_PREFIX_SEPARATOR + device.getAppNamespace()); dest.getExt().setNet(new NetExtension()); dest.getExt().getNet().setProvider(device.getCarrierName());
@Override public void read(JSONObject object) throws JSONException { /* Override abstract log JSON since it's Common Schema and not App Center schema. */ /* Read top level PART A simple fields. */ setVer(object.getString(VER)); setName(object.getString(NAME)); setTimestamp(JSONDateUtils.toDate(object.getString(TIME))); if (object.has(POP_SAMPLE)) { setPopSample(object.getDouble(POP_SAMPLE)); } setIKey(object.optString(IKEY, null)); setFlags(JSONUtils.readLong(object, FLAGS)); setCV(object.optString(CV, null)); /* Read extensions. */ if (object.has(EXT)) { Extensions extensions = new Extensions(); extensions.read(object.getJSONObject(EXT)); setExt(extensions); } /* Read Parts B&C. */ if (object.has(DATA)) { Data data = new Data(); data.read(object.getJSONObject(DATA)); setData(data); } }
/** * Utility for getLogsFilteringOutPausedTargetKeys test. */ private void generateCsLogsWithIKey(DatabasePersistence persistence, String iKey, int numberOfLogsPerKey) throws PersistenceException { for (int i = 0; i < numberOfLogsPerKey; i++) { CommonSchemaLog log = new MockCommonSchemaLog(); log.setVer("3.0"); log.setName("test"); log.setTimestamp(new Date()); log.setIKey(iKey); log.addTransmissionTarget(iKey + "-token"); persistence.putLog(log, "test", PERSISTENCE_NORMAL); } }
@Test public void collectDeviceId() { CommonSchemaLog log = new CommonSchemaEventLog(); log.setExt(new Extensions()); log.getExt().setDevice(new DeviceExtension()); /* Mock context. */ mockStatic(Secure.class); when(Secure.getString(any(ContentResolver.class), anyString())).thenReturn("mockDeviceId"); /* Get property configurator and collect device ID. */ PropertyConfigurator pc = Analytics.getTransmissionTarget("test").getPropertyConfigurator(); pc.collectDeviceId(); /* Simulate what the pipeline does to convert from App Center to Common Schema. */ log.addTransmissionTarget("test"); log.setTag(Analytics.getTransmissionTarget("test")); pc.onPreparingLog(log, "groupName"); /* Assert device ID is collected. */ assertEquals("a:mockDeviceId", log.getExt().getDevice().getLocalId()); }
largeValue.append("x"); log.setVer("3.0"); log.setName("test"); log.setTimestamp(new Date()); log.addTransmissionTarget("token"); Data data = new Data(); log.setData(data); data.getProperties().put("key", largeValue.toString());
log1.setIKey("t1"); Extensions ext1 = new Extensions(); ext1.setSdk(new SdkExtension()); log1.setExt(ext1); log2.setIKey("t1"); Extensions ext2 = new Extensions(); ext2.setSdk(new SdkExtension()); log2.setExt(ext2); assertEquals(Long.valueOf(DEFAULTS), log1.getFlags()); assertEquals(Long.valueOf(DEFAULTS), log2.getFlags()); assertNotNull(log1.getExt().getSdk().getEpoch()); assertEquals(log1.getExt().getSdk().getEpoch(), log2.getExt().getSdk().getEpoch()); assertEquals(Long.valueOf(1), log1.getExt().getSdk().getSeq()); assertEquals(Long.valueOf(2), log2.getExt().getSdk().getSeq()); assertEquals(installId, log1.getExt().getSdk().getInstallId()); assertEquals(installId, log2.getExt().getSdk().getInstallId()); log3.setIKey("t2"); Extensions ext3 = new Extensions(); ext3.setSdk(new SdkExtension()); log3.setExt(ext3); when(logSerializer.toCommonSchemaLog(any(Log.class))).thenReturn(Collections.singletonList(log3)); listener.onPreparedLog(originalLog, TEST_GROUP, PERSISTENCE_CRITICAL); assertEquals(Long.valueOf(PERSISTENCE_CRITICAL), log3.getFlags());
/** * Add ticket to common schema logs. */ private static void addTicketToLog(@NonNull Log log) { /* Decorate only common schema logs when an authentication provider was registered. */ if (sAuthenticationProvider != null && log instanceof CommonSchemaLog) { /* Add ticket reference to log. */ CommonSchemaLog csLog = (CommonSchemaLog) log; String ticketKey = sAuthenticationProvider.getTicketKeyHash(); csLog.getExt().getProtocol().setTicketKeys(Collections.singletonList(ticketKey)); /* * Check if we should try to refresh token if soon expired. * Known corner case: if already expired and refresh takes longer than batching log time, * then next logs will be anonymous until token refreshed. */ sAuthenticationProvider.checkTokenExpiry(); } }
commonSchemaLog.setFlags((long) flags); EpochAndSeq epochAndSeq = mEpochsAndSeqsByIKey.get(commonSchemaLog.getIKey()); if (epochAndSeq == null) { epochAndSeq = new EpochAndSeq(UUIDUtils.randomUUID().toString()); mEpochsAndSeqsByIKey.put(commonSchemaLog.getIKey(), epochAndSeq); SdkExtension sdk = commonSchemaLog.getExt().getSdk(); sdk.setEpoch(epochAndSeq.epoch); sdk.setSeq(++epochAndSeq.seq);
}}; final CommonSchemaLog log1 = mock(CommonSchemaLog.class); when(log1.getExt()).thenReturn(ext); when(log1.getTransmissionTargetTokens()).thenReturn(Collections.singleton("token1")); final CommonSchemaLog log2 = mock(CommonSchemaLog.class); when(log2.getExt()).thenReturn(ext); when(log2.getTransmissionTargetTokens()).thenReturn(new HashSet<>(Arrays.asList("token2", "token3"))); LogContainer container = new LogContainer() {{ setLogs(new ArrayList<Log>() {{
@Override public Object answer(InvocationOnMock invocation) { ProtocolExtension protocol = new ProtocolExtension(); Extensions ext = new Extensions(); ext.setProtocol(protocol); CommonSchemaLog log = new CommonSchemaEventLog(); log.setExt(ext); sentLogs.add(log); /* Call the listener after conversion of common schema for authentication decoration. */ AnalyticsTransmissionTarget.getChannelListener().onPreparingLog(log, "test"); return null; } }).when(mChannel).enqueue(any(Log.class), anyString(), anyInt());
private static void testValidName(String name) { CommonSchemaLog log = new MockCommonSchemaLog(); PartAUtils.setName(log, name); assertEquals(name, log.getName()); }
@Test public void coverJSONException() throws Exception { /* Fake JSON exception to cover the checked exception that never happens. */ JSONObject value = mock(JSONObject.class); whenNew(JSONObject.class).withNoArguments().thenReturn(value); when(value.put(anyString(), any())).thenThrow(new JSONException("mock")); CommonSchemaLog commonSchemaLog = new MockCommonSchemaLog(); List<TypedProperty> properties = new ArrayList<>(); StringTypedProperty stringTypedProperty = new StringTypedProperty(); stringTypedProperty.setName("a"); stringTypedProperty.setValue("b"); properties.add(stringTypedProperty); CommonSchemaDataUtils.addCommonSchemaData(properties, commonSchemaLog); assertEquals(0, commonSchemaLog.getData().getProperties().length()); } }
/** * Validate and set name for common schema log. * * @param log log. * @param name name. * @throws IllegalArgumentException if name is invalid. */ public static void setName(CommonSchemaLog log, String name) throws IllegalArgumentException { if (name == null) { throw new IllegalArgumentException("Name cannot be null."); } if (!NAME_REGEX.matcher(name).matches()) { throw new IllegalArgumentException("Name must match '" + NAME_REGEX + "' but was '" + name + "'."); } log.setName(name); }
@Test public void setNonPrefixUserId() { CommonSchemaLog log = new CommonSchemaEventLog(); log.setExt(new Extensions()); log.getExt().setUser(new UserExtension()); /* Get property configurator and set properties. */ PropertyConfigurator pc = Analytics.getTransmissionTarget("test").getPropertyConfigurator(); pc.setUserId("bob"); /* Simulate what the pipeline does to convert from App Center to Common Schema. */ log.addTransmissionTarget("test"); log.setTag(Analytics.getTransmissionTarget("test")); pc.onPreparingLog(log, "groupName"); /* Check prefix was added. */ assertEquals("c:bob", log.getExt().getUser().getLocalId()); }
List<String> ticketKeys = ((CommonSchemaLog) log).getExt().getProtocol().getTicketKeys(); if (ticketKeys != null) { for (String ticketKey : ticketKeys) {
ext.setProtocol(protocol); CommonSchemaLog log = new CommonSchemaEventLog(); log.setExt(ext); AnalyticsTransmissionTarget.getChannelListener().onPreparingLog(log, "test");
private static void testInvalidName(String name) { CommonSchemaLog log = new MockCommonSchemaLog(); try { PartAUtils.setName(log, name); fail("Expected exception"); } catch (IllegalArgumentException e) { assertNull(log.getName()); } }