Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
jan-goral committed Aug 5, 2021
1 parent 7c0dfd6 commit 3a8ab09
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 86 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package flank.tool.analytics.mixpanel

import flank.tool.analytics.mixpanel.internal.addToReport
import flank.tool.analytics.mixpanel.internal.anonymizeSensitiveValues
import flank.tool.analytics.mixpanel.internal.configureReport
import flank.tool.analytics.mixpanel.internal.removeSensitiveValues
import flank.tool.analytics.mixpanel.internal.objectToMap
import flank.tool.analytics.mixpanel.internal.removeNotNeededKeys
import flank.tool.analytics.mixpanel.internal.sendReport
Expand Down Expand Up @@ -38,7 +38,7 @@ object Mixpanel {
statisticClasses = statisticClasses
)

fun removeSensitiveValues(map: ObjectMap): ObjectMap = map.removeNotNeededKeys().removeSensitiveValues()
fun removeSensitiveValues(map: ObjectMap): ObjectMap = map.removeNotNeededKeys().anonymizeSensitiveValues()

fun add(key: String, reportNode: Any): Unit = addToReport(key, reportNode)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package flank.tool.analytics.mixpanel.internal

internal fun addToReport(key: String, reportNode: Any) {
Report.data[key] = reportNode
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package flank.tool.analytics.mixpanel.internal

import flank.tool.analytics.AnonymizeInStatistics
import flank.tool.analytics.IgnoreInStatistics
import kotlin.reflect.KClass

internal fun configureReport(
projectName: String,
blockUsageStatistics: Boolean,
statisticClasses: Array<out KClass<*>>
) {
Report.projectName = projectName
Report.blockSendUsageStatistics = blockUsageStatistics
Report.keysToRemove = statisticClasses getMembersWith AnonymizeInStatistics::class
Report.keysToAnonymize = statisticClasses getMembersWith IgnoreInStatistics::class
}

private infix fun Array<out KClass<*>>.getMembersWith(
annotationType: KClass<*>
): Set<String> =
flatMap { type ->
type.members.filter { member ->
member.annotations.any { annotation ->
annotation.annotationClass == annotationType
}
}
}.map { member ->
member.name
}.toSet()
Original file line number Diff line number Diff line change
@@ -1,46 +1,23 @@
package flank.tool.analytics.mixpanel.internal

import flank.tool.analytics.AnonymizeInStatistics
import flank.tool.analytics.IgnoreInStatistics
import flank.tool.analytics.mixpanel.ObjectMap
import kotlin.reflect.KCallable
import kotlin.reflect.KClass

// ============================Remove not needed ============================

internal fun ObjectMap.removeNotNeededKeys(): ObjectMap = filterNot { (key, _) -> key in keysToRemove }

private val keysToRemove by lazy {
getClassesForStatisticsOrThrow()
.map(findMembersWithAnnotation(IgnoreInStatistics::class))
.flatten()
}

// ============================ Remove sensitive ============================

internal fun ObjectMap.removeSensitiveValues(): ObjectMap = mapValues { (key, value) ->
when {
key !in keysToAnonymize -> value
value is Map<*, *> -> value.mapValues { ANONYMIZE_VALUE }
value is List<*> -> "Count: $size"
else -> ANONYMIZE_VALUE
internal fun ObjectMap.removeNotNeededKeys(
keysToRemove: Set<String> = Report.keysToAnonymize
): ObjectMap =
if (keysToRemove.isEmpty()) this
else filterNot { (key, _) -> key in Report.keysToRemove }

internal fun ObjectMap.anonymizeSensitiveValues(
keysToAnonymize: Set<String> = Report.keysToAnonymize,
anonymousValue: String = "...",
): ObjectMap =
if (keysToAnonymize.isEmpty()) this
else mapValues { (key, value) ->
when {
key !in keysToAnonymize -> value
value is Map<*, *> -> value.mapValues { anonymousValue }
value is List<*> -> "Count: ${value.size}"
else -> anonymousValue
}
}
}

private val keysToAnonymize by lazy {
getClassesForStatisticsOrThrow()
.map(findMembersWithAnnotation(AnonymizeInStatistics::class))
.flatten()
}

private const val ANONYMIZE_VALUE = "..."

// ============================ Common ============================

private fun getClassesForStatisticsOrThrow() =
(Report.classesForStatistics ?: throw NullPointerException("Analytics client should be initialized first"))

private fun findMembersWithAnnotation(annotationType: KClass<*>) = fun KClass<*>.() = members
.filter { member -> member.annotations.any { annotation -> annotation.annotationClass == annotationType } }
.map(KCallable<*>::name)

Original file line number Diff line number Diff line change
@@ -1,36 +1,12 @@
package flank.tool.analytics.mixpanel.internal

import flank.tool.analytics.mixpanel.internal.send.sendConfiguration
import kotlin.reflect.KClass

internal object Report {
// Configuration
var projectName: String = ""
var blockSendUsageStatistics: Boolean = false
var classesForStatistics: List<KClass<*>>? = null
val data: MutableMap<String, Any> = mutableMapOf()
}

internal fun initStatisticsClient(blockUsageStatistics: Boolean, statisticClasses: Array<out KClass<*>>) {
// TODO Verify if condition is needed
if (Report.classesForStatistics != null) return
Report.blockSendUsageStatistics = blockUsageStatistics
Report.classesForStatistics = statisticClasses.asList()
}
var keysToRemove: Set<String> = emptySet()
var keysToAnonymize: Set<String> = emptySet()

internal fun configureReport(
projectName: String,
blockUsageStatistics: Boolean,
statisticClasses: Array<out KClass<*>>
) {
Report.projectName = projectName
Report.blockSendUsageStatistics = blockUsageStatistics
Report.classesForStatistics = statisticClasses.asList()
}

internal fun addToReport(key: String, reportNode: Any) {
Report.data[key] = reportNode
}

internal fun sendReport(eventName: String) {
sendConfiguration(Report.projectName, Report.data, eventName)
// Accumulated data
val data: MutableMap<String, Any> = mutableMapOf()
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
package flank.tool.analytics.mixpanel.internal.send
package flank.tool.analytics.mixpanel.internal

import com.mixpanel.mixpanelapi.MessageBuilder
import com.mixpanel.mixpanelapi.MixpanelAPI
import flank.tool.analytics.mixpanel.Mixpanel.PROJECT_ID
import flank.tool.analytics.mixpanel.Mixpanel.PROJECT_NAME
import flank.tool.analytics.mixpanel.Mixpanel.SESSION_ID
import flank.tool.analytics.mixpanel.Mixpanel.sessionId
import flank.tool.analytics.mixpanel.internal.Report
import org.json.JSONObject

internal fun sendConfiguration(
project: String,
events: Map<String, Any?>,
eventName: String
internal fun sendReport(
eventName: String,
) {
!Report.blockSendUsageStatistics || return
project.isNotBlank() || return
Report.projectName.isNotBlank() || return
listOf(
createUser(project),
createEvent(project, eventName, events),
createUser(Report.projectName),
createEvent(Report.projectName, eventName, Report.data),
).forEach(apiClient::sendMessage)
}

Expand Down Expand Up @@ -46,10 +43,7 @@ private fun createEvent(
JSONObject(data + (SESSION_ID to sessionId))
)

internal val messageBuilder by lazy { MessageBuilder(MIXPANEL_API_TOKEN) }

internal val apiClient by lazy { MixpanelAPI() }
private val messageBuilder by lazy { MessageBuilder(MIXPANEL_API_TOKEN) }
private val apiClient by lazy { MixpanelAPI() }

private const val MIXPANEL_API_TOKEN = "d9728b2c8e6ca9fd6de1fcd32dd8cdc2"


0 comments on commit 3a8ab09

Please sign in to comment.