Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add keys/strings as a metric #2942

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .run/Frontend localhost.run.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Frontend localhost" type="js.build_tools.npm">
<package-json value="$PROJECT_DIR$/webapp/package.json" />
<package-json value="$PROJECT_DIR$/public/webapp/package.json" />
<command value="run" />
<scripts>
<script value="start" />
Expand All @@ -9,4 +9,4 @@
<envs />
<method v="2" />
</configuration>
</component>
</component>
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ class OrganizationController(
@PathVariable("organizationId") organizationId: Long,
@PathVariable("userId") userId: Long,
) {
organizationRoleService.removeUser(organizationId, userId)
organizationRoleService.removeUser(userId, organizationId)
}

@PutMapping("/{id:[0-9]+}/avatar", consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ class ProjectsController(
if (userId == authenticationFacade.authenticatedUser.id) {
throw BadRequestException(Message.CAN_NOT_REVOKE_OWN_PERMISSIONS)
}
permissionService.revoke(projectId, userId)
permissionService.revoke(userId, projectId)
}

@PutMapping(value = ["/{projectId:[0-9]+}/leave"])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import org.springframework.web.bind.annotation.RestController

@RestController
@CrossOrigin(origins = ["*"])
@RequestMapping("/v2/auth-provider") // TODO: I should probably use the v2
@RequestMapping("/v2/auth-provider")
@AuthenticationTag
@OpenApiHideFromPublicDocs
class AuthProviderChangeController(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ open class PlanIncludedUsageModel(
var translationSlots: Long = -1L,
var translations: Long = -1L,
var mtCredits: Long = -1L,
var keys: Long = -1L,
) : RepresentationModel<PlanIncludedUsageModel>(), Serializable
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@ open class PlanPricesModel(
val perThousandMtCredits: BigDecimal? = BigDecimal.ZERO,
val subscriptionMonthly: BigDecimal = BigDecimal.ZERO,
val subscriptionYearly: BigDecimal = BigDecimal.ZERO,
val perThousandKeys: BigDecimal = BigDecimal.ZERO,
) : RepresentationModel<PlanPricesModel>(), Serializable

// TODO: Test it always counts usage, to handle situation when user switches between free plan, strings or key based plans.
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class OrganizationRoleCachingTest : AbstractSpringTest() {
@Test
fun `it evicts on remove user`() {
populateCache(testData.pepaOrg.id, testData.pepa.id)
organizationRoleService.removeUser(testData.pepaOrg.id, testData.pepa.id)
organizationRoleService.removeUser(testData.pepa.id, testData.pepaOrg.id)
assertCacheEvicted(testData.pepaOrg.id, testData.pepa.id)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class ActivityDatabaseInterceptor : Interceptor, Logging {
propertyNames: Array<out String>?,
types: Array<out Type>?,
): Boolean {
preCommitEventsPublisher.onUpdate(entity)
preCommitEventsPublisher.onUpdate(entity, previousState, propertyNames)
interceptedEventsManager.onFieldModificationsActivity(
entity,
currentState,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ class PreCommitEventPublisher(private val applicationContext: ApplicationContext
applicationContext.publishEvent(OnEntityPrePersist(this, entity))
}

fun onUpdate(entity: Any?) {
applicationContext.publishEvent(OnEntityPreUpdate(this, entity))
fun onUpdate(entity: Any?, previousState: Array<out Any>?, propertyNames: Array<out String>?) {
applicationContext.publishEvent(OnEntityPreUpdate(this, entity, previousState, propertyNames))
}

fun onDelete(entity: Any?) {
Expand Down
2 changes: 2 additions & 0 deletions backend/data/src/main/kotlin/io/tolgee/constants/Message.kt
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,8 @@ enum class Message {
CANNOT_UPDATE_WITHOUT_MODIFICATION,
CURRENT_SUBSCRIPTION_IS_NOT_TRIALING,
SORTING_AND_PAGING_IS_NOT_SUPPORTED_WHEN_USING_CURSOR,
STRINGS_METRIC_ARE_NOT_SUPPORTED,
KEYS_SEATS_METRIC_ARE_NOT_SUPPORTED_FOR_SLOTS_FIXED_TYPE,
;

val code: String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ interface AdditionalTestDataSaver {
fun save(builder: TestDataBuilder)

fun clean(builder: TestDataBuilder)

fun before(builder: TestDataBuilder) {}

fun after(builder: TestDataBuilder) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class TestDataService(
fun saveTestData(builder: TestDataBuilder) {
activityHolder.enableAutoCompletion = false
languageStatsListener.bypass = true
runBeforeMethodsOfAdditionalSavers(builder)
prepare()

// Projects have to be stored in separate transaction since projectHolder's
Expand All @@ -88,8 +89,8 @@ class TestDataService(
// To be able to save project in its separate transaction,
// user/organization has to be stored first.
executeInNewTransaction(transactionManager) {
saveOrganizationData(builder)
saveAllUsers(builder)
saveOrganizationData(builder)
}

executeInNewTransaction(transactionManager) {
Expand All @@ -107,6 +108,8 @@ class TestDataService(
updateLanguageStats(builder)
activityHolder.enableAutoCompletion = true
languageStatsListener.bypass = false

runAfterMethodsOfAdditionalSavers(builder)
}

@Transactional
Expand Down Expand Up @@ -520,4 +523,21 @@ class TestDataService(
companion object {
private val passwordHashCache = mutableMapOf<String, String>()
}

private fun runBeforeMethodsOfAdditionalSavers(builder: TestDataBuilder) {
executeInNewTransaction(transactionManager) {
additionalTestDataSavers.forEach {
it.before(builder)
}
}
}


private fun runAfterMethodsOfAdditionalSavers(builder: TestDataBuilder) {
executeInNewTransaction(transactionManager) {
additionalTestDataSavers.forEach {
it.after(builder)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ import org.springframework.context.ApplicationEvent
class OnEntityPreUpdate(
override val source: PreCommitEventPublisher,
override val entity: Any?,
val previousState: Array<out Any>?,
val propertyNames: Array<out String>?,
) : ApplicationEvent(source), EntityPreCommitEvent
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package io.tolgee.events

import io.tolgee.model.Organization

class OnOrganizationNameUpdated(
val oldName: String,
val organization: Organization,
)
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
package io.tolgee.model

import io.tolgee.model.enums.OrganizationRoleType
import jakarta.persistence.Entity
import jakarta.persistence.EnumType
import jakarta.persistence.Enumerated
import jakarta.persistence.ManyToOne
import jakarta.persistence.OneToOne
import jakarta.persistence.Table
import jakarta.persistence.UniqueConstraint
import jakarta.persistence.*
import jakarta.validation.constraints.NotNull
import org.hibernate.annotations.ColumnDefault

Expand Down
24 changes: 5 additions & 19 deletions backend/data/src/main/kotlin/io/tolgee/model/Permission.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,10 @@ import io.tolgee.dtos.request.project.LanguagePermissions
import io.tolgee.model.enums.ProjectPermissionType
import io.tolgee.model.enums.Scope
import io.tolgee.model.translationAgency.TranslationAgency
import jakarta.persistence.Column
import jakarta.persistence.Entity
import jakarta.persistence.EntityListeners
import jakarta.persistence.EnumType
import jakarta.persistence.Enumerated
import jakarta.persistence.FetchType
import jakarta.persistence.GeneratedValue
import jakarta.persistence.GenerationType
import jakarta.persistence.Id
import jakarta.persistence.Index
import jakarta.persistence.JoinColumn
import jakarta.persistence.JoinTable
import jakarta.persistence.ManyToMany
import jakarta.persistence.ManyToOne
import jakarta.persistence.OneToOne
import jakarta.persistence.PrePersist
import jakarta.persistence.PreUpdate
import jakarta.persistence.Table
import jakarta.persistence.*
import org.hibernate.annotations.Parameter
import org.hibernate.annotations.Type
import org.springframework.beans.factory.annotation.Configurable

@Suppress("LeakingThis")
@Entity
Expand Down Expand Up @@ -156,7 +140,9 @@ class Permission(
get() = this.stateChangeLanguages.map { it.id }.toSet()

companion object {
@Configurable
class PermissionListeners {

@PrePersist
@PreUpdate
fun prePersist(permission: Permission) {
Expand All @@ -170,7 +156,7 @@ class Permission(
permission.viewLanguages.isNotEmpty() ||
permission.translateLanguages.isNotEmpty() ||
permission.stateChangeLanguages.isNotEmpty()
)
)
) {
throw IllegalStateException("Organization base permission cannot have language permissions")
}
Expand Down
4 changes: 0 additions & 4 deletions backend/data/src/main/kotlin/io/tolgee/model/Project.kt
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,6 @@ class Project(
return findLanguageOptional(tag).orElse(null)
}

fun getLanguage(tag: String): Language {
return findLanguage(tag) ?: throw NotFoundException()
}

companion object {
@Configurable
class ProjectListener {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

@Service
@Transactional
class OrganizationRoleService(
private val organizationRoleRepository: OrganizationRoleRepository,
private val authenticationFacade: AuthenticationFacade,
Expand Down Expand Up @@ -210,6 +209,7 @@ class OrganizationRoleService(
}

@CacheEvict(Caches.ORGANIZATION_ROLES, key = "{#organization.id, #user.id}")
@Transactional
fun grantRoleToUser(
user: UserAccount,
organization: Organization,
Expand All @@ -228,12 +228,13 @@ class OrganizationRoleService(
}

fun leave(organizationId: Long) {
this.removeUser(organizationId, authenticationFacade.authenticatedUser.id)
this.removeUser(authenticationFacade.authenticatedUser.id, organizationId)
}

@Transactional
fun removeUser(
organizationId: Long,
userId: Long,
organizationId: Long,
) {
val managedBy = getManagedBy(userId)
if (managedBy != null && managedBy.id == organizationId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -401,8 +401,8 @@ class PermissionService(
}

fun revoke(
projectId: Long,
userId: Long,
projectId: Long,
) {
val data = this.getProjectPermissionData(projectId, userId)
if (data.organizationRole != null) {
Expand Down
19 changes: 19 additions & 0 deletions backend/data/src/main/kotlin/io/tolgee/util/BypassableListener.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package io.tolgee.util

interface BypassableListener {
var bypass: Boolean

fun <T> bypassingListener(fn: () -> T): T {
val oldBypass = bypass
bypass = true
val ret = fn()
bypass = oldBypass
return ret
}

fun <T> executeIfNotBypassed(fn: () -> T) {
if (!bypass) {
fn()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ interface Logging {
}
}

inline fun <reified T> T.logger(): Logger {
return LoggerFactory.getLogger(T::class.java)
}

val <T : Logging> T.logger: Logger get() = LoggerFactory.getLogger(javaClass)

fun Logger.trace(message: () -> String) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.tolgee.controllers.internal.e2eData

import io.tolgee.data.StandardTestDataResult
import io.tolgee.data.service.TestDataGeneratingService
import io.tolgee.development.testDataBuilder.TestDataService
import io.tolgee.development.testDataBuilder.builders.TestDataBuilder
import io.tolgee.service.organization.OrganizationService
Expand Down Expand Up @@ -40,32 +42,15 @@ abstract class AbstractE2eDataController {
@Autowired
private lateinit var applicationContext: ApplicationContext

@Autowired
private lateinit var testDataGeneratingService: TestDataGeneratingService

open fun afterTestDataStored(data: TestDataBuilder) {}

@GetMapping(value = ["/generate-standard"])
@Transactional
open fun generate(): StandardTestDataResult {
val data = this.testData
testDataService.saveTestData(data)
afterTestDataStored(data)
return getStandardResult(data)
}

fun getStandardResult(data: TestDataBuilder): StandardTestDataResult {
return StandardTestDataResult(
projects =
data.data.projects.map {
StandardTestDataResult.ProjectModel(name = it.self.name, id = it.self.id)
},
users =
data.data.userAccounts.map {
StandardTestDataResult.UserModel(name = it.self.name, username = it.self.username, id = it.self.id)
},
organizations =
data.data.organizations.map {
StandardTestDataResult.OrganizationModel(id = it.self.id, name = it.self.name, slug = it.self.slug)
},
)
return testDataGeneratingService.generate(testData, this::afterTestDataStored)
}

@GetMapping(value = ["/clean"])
Expand All @@ -82,27 +67,4 @@ abstract class AbstractE2eDataController {
}
}
}

data class StandardTestDataResult(
val projects: List<ProjectModel>,
val users: List<UserModel>,
val organizations: List<OrganizationModel>,
) {
data class UserModel(
val name: String,
val username: String,
val id: Long,
)

data class ProjectModel(
val name: String,
val id: Long,
)

data class OrganizationModel(
val id: Long,
val slug: String,
val name: String,
)
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.tolgee.controllers.internal.e2eData

import io.swagger.v3.oas.annotations.Hidden
import io.tolgee.data.StandardTestDataResult
import io.tolgee.development.testDataBuilder.builders.TestDataBuilder
import io.tolgee.development.testDataBuilder.data.PermissionsTestData
import io.tolgee.model.enums.ProjectPermissionType
Expand Down
Loading
Loading