Add new event logging module
This commit is contained in:
parent
6119b6ab89
commit
a4508ec84f
|
@ -1135,7 +1135,7 @@ ij_kotlin_field_annotation_wrap = split_into_lines
|
||||||
ij_kotlin_finally_on_new_line = false
|
ij_kotlin_finally_on_new_line = false
|
||||||
ij_kotlin_if_rparen_on_new_line = false
|
ij_kotlin_if_rparen_on_new_line = false
|
||||||
ij_kotlin_import_nested_classes = false
|
ij_kotlin_import_nested_classes = false
|
||||||
ij_kotlin_imports_layout = *,java.**,javax.**,kotlin.**,^
|
ij_kotlin_imports_layout = *
|
||||||
ij_kotlin_insert_whitespaces_in_simple_one_line_method = true
|
ij_kotlin_insert_whitespaces_in_simple_one_line_method = true
|
||||||
ij_kotlin_keep_blank_lines_before_right_brace = 2
|
ij_kotlin_keep_blank_lines_before_right_brace = 2
|
||||||
ij_kotlin_keep_blank_lines_in_code = 2
|
ij_kotlin_keep_blank_lines_in_code = 2
|
||||||
|
@ -1151,9 +1151,9 @@ ij_kotlin_method_call_chain_wrap = off
|
||||||
ij_kotlin_method_parameters_new_line_after_left_paren = false
|
ij_kotlin_method_parameters_new_line_after_left_paren = false
|
||||||
ij_kotlin_method_parameters_right_paren_on_new_line = false
|
ij_kotlin_method_parameters_right_paren_on_new_line = false
|
||||||
ij_kotlin_method_parameters_wrap = off
|
ij_kotlin_method_parameters_wrap = off
|
||||||
ij_kotlin_name_count_to_use_star_import = 5
|
ij_kotlin_name_count_to_use_star_import = 999
|
||||||
ij_kotlin_name_count_to_use_star_import_for_members = 3
|
ij_kotlin_name_count_to_use_star_import_for_members = 999
|
||||||
ij_kotlin_packages_to_use_import_on_demand = java.util.*,kotlinx.android.synthetic.**,io.ktor.**
|
ij_kotlin_packages_to_use_import_on_demand =
|
||||||
ij_kotlin_parameter_annotation_wrap = off
|
ij_kotlin_parameter_annotation_wrap = off
|
||||||
ij_kotlin_space_after_comma = true
|
ij_kotlin_space_after_comma = true
|
||||||
ij_kotlin_space_after_extend_colon = true
|
ij_kotlin_space_after_extend_colon = true
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright 2022 Signal Messenger, LLC
|
||||||
|
~ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
-->
|
||||||
|
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>TextSecureServer</artifactId>
|
||||||
|
<groupId>org.whispersystems.textsecure</groupId>
|
||||||
|
<version>JGITVER</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<artifactId>event-logger</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.cloud</groupId>
|
||||||
|
<artifactId>google-cloud-logging</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-stdlib</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlinx</groupId>
|
||||||
|
<artifactId>kotlinx-serialization-json</artifactId>
|
||||||
|
<version>${kotlinx-serialization.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
|
||||||
|
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
|
||||||
|
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-maven-plugin</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>compile</id>
|
||||||
|
<goals>
|
||||||
|
<goal>compile</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
|
||||||
|
<execution>
|
||||||
|
<id>test-compile</id>
|
||||||
|
<goals>
|
||||||
|
<goal>test-compile</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<compilerPlugins>
|
||||||
|
<plugin>kotlinx-serialization</plugin>
|
||||||
|
</compilerPlugins>
|
||||||
|
</configuration>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-maven-serialization</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2022 Signal Messenger, LLC
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.signal.event
|
||||||
|
|
||||||
|
import java.util.Collections
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
sealed interface Event
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class RemoteConfigSetEvent(val token: String, val name: String, val percentage: Int, val defaultValue: String? = null, val value: String? = null, val hashKey: String? = null, val uuids: Collection<String> = Collections.emptyList()) : Event
|
|
@ -0,0 +1,15 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2022 Signal Messenger, LLC
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.signal.event
|
||||||
|
|
||||||
|
interface Logger {
|
||||||
|
fun logEvent(event: Event, labels: Map<String, String>?)
|
||||||
|
fun logEvent(event: Event) = logEvent(event, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
class NoOpLogger : Logger {
|
||||||
|
override fun logEvent(event: Event, labels: Map<String, String>?) {}
|
||||||
|
}
|
3
pom.xml
3
pom.xml
|
@ -35,6 +35,7 @@
|
||||||
</pluginRepositories>
|
</pluginRepositories>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
<module>event-logger</module>
|
||||||
<module>redis-dispatch</module>
|
<module>redis-dispatch</module>
|
||||||
<module>websocket-resources</module>
|
<module>websocket-resources</module>
|
||||||
<module>service</module>
|
<module>service</module>
|
||||||
|
@ -53,6 +54,8 @@
|
||||||
<jackson.version>2.13.3</jackson.version>
|
<jackson.version>2.13.3</jackson.version>
|
||||||
<jaxb.version>2.3.1</jaxb.version>
|
<jaxb.version>2.3.1</jaxb.version>
|
||||||
<jedis.version>2.9.0</jedis.version>
|
<jedis.version>2.9.0</jedis.version>
|
||||||
|
<kotlin.version>1.7.10</kotlin.version>
|
||||||
|
<kotlinx-serialization.version>1.4.0</kotlinx-serialization.version>
|
||||||
<lettuce.version>6.1.9.RELEASE</lettuce.version>
|
<lettuce.version>6.1.9.RELEASE</lettuce.version>
|
||||||
<libphonenumber.version>8.12.54</libphonenumber.version>
|
<libphonenumber.version>8.12.54</libphonenumber.version>
|
||||||
<logstash.logback.version>7.0.1</logstash.logback.version>
|
<logstash.logback.version>7.0.1</logstash.logback.version>
|
||||||
|
|
|
@ -24,6 +24,11 @@
|
||||||
<artifactId>jakarta.ws.rs-api</artifactId>
|
<artifactId>jakarta.ws.rs-api</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.whispersystems.textsecure</groupId>
|
||||||
|
<artifactId>event-logger</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.whispersystems.textsecure</groupId>
|
<groupId>org.whispersystems.textsecure</groupId>
|
||||||
<artifactId>redis-dispatch</artifactId>
|
<artifactId>redis-dispatch</artifactId>
|
||||||
|
|
|
@ -55,6 +55,7 @@ import javax.servlet.FilterRegistration;
|
||||||
import javax.servlet.ServletRegistration;
|
import javax.servlet.ServletRegistration;
|
||||||
import org.eclipse.jetty.servlets.CrossOriginFilter;
|
import org.eclipse.jetty.servlets.CrossOriginFilter;
|
||||||
import org.glassfish.jersey.server.ServerProperties;
|
import org.glassfish.jersey.server.ServerProperties;
|
||||||
|
import org.signal.event.NoOpLogger;
|
||||||
import org.signal.i18n.HeaderControlledResourceBundleLookup;
|
import org.signal.i18n.HeaderControlledResourceBundleLookup;
|
||||||
import org.signal.libsignal.zkgroup.ServerSecretParams;
|
import org.signal.libsignal.zkgroup.ServerSecretParams;
|
||||||
import org.signal.libsignal.zkgroup.auth.ServerZkAuthOperations;
|
import org.signal.libsignal.zkgroup.auth.ServerZkAuthOperations;
|
||||||
|
@ -644,7 +645,7 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
||||||
new PaymentsController(currencyManager, paymentsCredentialsGenerator),
|
new PaymentsController(currencyManager, paymentsCredentialsGenerator),
|
||||||
new ProfileController(clock, rateLimiters, accountsManager, profilesManager, dynamicConfigurationManager, profileBadgeConverter, config.getBadges(), cdnS3Client, profileCdnPolicyGenerator, profileCdnPolicySigner, config.getCdnConfiguration().getBucket(), zkProfileOperations, batchIdentityCheckExecutor),
|
new ProfileController(clock, rateLimiters, accountsManager, profilesManager, dynamicConfigurationManager, profileBadgeConverter, config.getBadges(), cdnS3Client, profileCdnPolicyGenerator, profileCdnPolicySigner, config.getCdnConfiguration().getBucket(), zkProfileOperations, batchIdentityCheckExecutor),
|
||||||
new ProvisioningController(rateLimiters, provisioningManager),
|
new ProvisioningController(rateLimiters, provisioningManager),
|
||||||
new RemoteConfigController(remoteConfigsManager, config.getRemoteConfigConfiguration().getAuthorizedTokens(), config.getRemoteConfigConfiguration().getGlobalConfig()),
|
new RemoteConfigController(remoteConfigsManager, new NoOpLogger(), config.getRemoteConfigConfiguration().getAuthorizedTokens(), config.getRemoteConfigConfiguration().getGlobalConfig()),
|
||||||
new SecureBackupController(backupCredentialsGenerator),
|
new SecureBackupController(backupCredentialsGenerator),
|
||||||
new SecureStorageController(storageCredentialsGenerator),
|
new SecureStorageController(storageCredentialsGenerator),
|
||||||
new StickerController(rateLimiters, config.getCdnConfiguration().getAccessKey(),
|
new StickerController(rateLimiters, config.getCdnConfiguration().getAccessKey(),
|
||||||
|
|
|
@ -14,6 +14,7 @@ import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -31,6 +32,8 @@ import javax.ws.rs.Produces;
|
||||||
import javax.ws.rs.WebApplicationException;
|
import javax.ws.rs.WebApplicationException;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
|
import org.signal.event.Logger;
|
||||||
|
import org.signal.event.RemoteConfigSetEvent;
|
||||||
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
|
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
|
||||||
import org.whispersystems.textsecuregcm.entities.UserRemoteConfig;
|
import org.whispersystems.textsecuregcm.entities.UserRemoteConfig;
|
||||||
import org.whispersystems.textsecuregcm.entities.UserRemoteConfigList;
|
import org.whispersystems.textsecuregcm.entities.UserRemoteConfigList;
|
||||||
|
@ -42,13 +45,15 @@ import org.whispersystems.textsecuregcm.util.Conversions;
|
||||||
public class RemoteConfigController {
|
public class RemoteConfigController {
|
||||||
|
|
||||||
private final RemoteConfigsManager remoteConfigsManager;
|
private final RemoteConfigsManager remoteConfigsManager;
|
||||||
private final List<String> configAuthTokens;
|
private final Logger eventLogger;
|
||||||
private final Map<String, String> globalConfig;
|
private final List<String> configAuthTokens;
|
||||||
|
private final Map<String, String> globalConfig;
|
||||||
|
|
||||||
private static final String GLOBAL_CONFIG_PREFIX = "global.";
|
private static final String GLOBAL_CONFIG_PREFIX = "global.";
|
||||||
|
|
||||||
public RemoteConfigController(RemoteConfigsManager remoteConfigsManager, List<String> configAuthTokens, Map<String, String> globalConfig) {
|
public RemoteConfigController(RemoteConfigsManager remoteConfigsManager, Logger eventLogger, List<String> configAuthTokens, Map<String, String> globalConfig) {
|
||||||
this.remoteConfigsManager = remoteConfigsManager;
|
this.remoteConfigsManager = remoteConfigsManager;
|
||||||
|
this.eventLogger = Objects.requireNonNull(eventLogger);
|
||||||
this.configAuthTokens = configAuthTokens;
|
this.configAuthTokens = configAuthTokens;
|
||||||
this.globalConfig = globalConfig;
|
this.globalConfig = globalConfig;
|
||||||
}
|
}
|
||||||
|
@ -88,6 +93,15 @@ public class RemoteConfigController {
|
||||||
throw new WebApplicationException(Response.Status.FORBIDDEN);
|
throw new WebApplicationException(Response.Status.FORBIDDEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eventLogger.logEvent(
|
||||||
|
new RemoteConfigSetEvent(
|
||||||
|
configToken,
|
||||||
|
config.getName(),
|
||||||
|
config.getPercentage(),
|
||||||
|
config.getDefaultValue(),
|
||||||
|
config.getValue(),
|
||||||
|
config.getHashKey(),
|
||||||
|
config.getUuids().stream().map(UUID::toString).collect(Collectors.toList())));
|
||||||
remoteConfigsManager.set(config);
|
remoteConfigsManager.set(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.signal.event.NoOpLogger;
|
||||||
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
|
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
|
||||||
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAuthenticatedAccount;
|
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAuthenticatedAccount;
|
||||||
import org.whispersystems.textsecuregcm.controllers.RemoteConfigController;
|
import org.whispersystems.textsecuregcm.controllers.RemoteConfigController;
|
||||||
|
@ -57,7 +58,7 @@ class RemoteConfigControllerTest {
|
||||||
ImmutableSet.of(AuthenticatedAccount.class, DisabledPermittedAuthenticatedAccount.class)))
|
ImmutableSet.of(AuthenticatedAccount.class, DisabledPermittedAuthenticatedAccount.class)))
|
||||||
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
|
.setTestContainerFactory(new GrizzlyWebTestContainerFactory())
|
||||||
.addProvider(new DeviceLimitExceededExceptionMapper())
|
.addProvider(new DeviceLimitExceededExceptionMapper())
|
||||||
.addResource(new RemoteConfigController(remoteConfigsManager, remoteConfigsAuth, Map.of("maxGroupSize", "42")))
|
.addResource(new RemoteConfigController(remoteConfigsManager, new NoOpLogger(), remoteConfigsAuth, Map.of("maxGroupSize", "42")))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue