Skip to content
Merged
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ out/
# generated
openapi/plantuml/.openapi-generator/
openapi/openapi.yaml
doc/generated-snippets

### Personal directory ###
perso
Expand Down
2 changes: 1 addition & 1 deletion api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ tasks.register<Copy>("copySubProjectsOpenAPIFiles") {
logger.debug("Found project dependency: $it")
it.name.matches("^cosmotech-[a-zA-Z]+-api$".toRegex())
}
.map { it.dependencyProject.projectDir }
.map { project.project(it.path).projectDir }
.map { file("${it}/src/main/openapi/${it.relativeTo(rootDir)}.yaml") }
.filter { it.exists() }
.map { it.absolutePath }
Expand Down

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions api/src/integrationTest/resources/application-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ csm:
base-path: /
base-url: "http://fake_url:8080"
version: latest
id-generator:
type: hashid
event-publisher:
type: in_process
upload:
Expand Down
2 changes: 0 additions & 2 deletions api/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@ csm:
base-path: /
base-url: "http://cosmotech-api-${csm.platform.api.version}:8080"
version: latest
id-generator:
type: hashid
event-publisher:
type: in_process
metrics:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ package com.cosmotech.common

import com.cosmotech.common.config.CsmPlatformProperties
import com.cosmotech.common.events.CsmEventPublisher
import com.cosmotech.common.id.CsmIdGenerator
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
Expand All @@ -16,7 +15,5 @@ abstract class CsmPhoenixService {

@Autowired protected lateinit var csmPlatformProperties: CsmPlatformProperties

@Autowired protected lateinit var idGenerator: CsmIdGenerator

@Autowired protected lateinit var eventPublisher: CsmEventPublisher
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ data class CsmPlatformProperties(
/** API Configuration */
val api: Api,

/** Id Generator */
val idGenerator: IdGenerator,

/** Event Publisher */
val eventPublisher: EventPublisher,

Expand Down Expand Up @@ -184,16 +181,6 @@ data class CsmPlatformProperties(
val basePath: String,
)

data class IdGenerator(val type: Type) {
enum class Type {
/** short unique UIDs */
HASHID,

/** UUIDs */
UUID
}
}

data class EventPublisher(val type: Type) {
enum class Type {
/** In-process, via Spring Application Events */
Expand Down
31 changes: 18 additions & 13 deletions common/src/main/kotlin/com/cosmotech/common/id/CsmIdGenerator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,26 @@
// Licensed under the MIT license.
package com.cosmotech.common.id

interface CsmIdGenerator {
import java.util.UUID
import kotlin.math.min
import org.hashids.Hashids
import org.hashids.Hashids.MAX_NUMBER

fun generate(scope: String, prependPrefix: String? = null): String
}

internal abstract class AbstractCsmIdGenerator : CsmIdGenerator {
private const val MIN_HASH_LENGTH = 0
private const val ALPHABET = "abcdefghijklmnopqrstuvwxyz0123456789"

final override fun generate(scope: String, prependPrefix: String?): String {
if (scope.isBlank()) {
throw IllegalArgumentException("scope must not be blank")
}

val id = this.buildId(scope)
return "${prependPrefix ?: "${scope[0].lowercaseChar()}-"}$id"
fun generateId(scope: String, prependPrefix: String? = null): String {
if (scope.isBlank()) {
throw IllegalArgumentException("scope must not be blank")
}

protected abstract fun buildId(scope: String): String
// We do not intend to decode generated IDs afterwards => we can safely generate a unique salt.
// This will give us different ids even with equal numbers to encode
val id =
Hashids("$scope-${UUID.randomUUID()}", MIN_HASH_LENGTH, ALPHABET)
.encode(
// PROD-8703: encodedElement might be higher than the maximum number supported
min(System.nanoTime(), MAX_NUMBER))

return "${prependPrefix ?: "${scope[0].lowercaseChar()}-"}$id"
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright (c) Cosmo Tech.
// Licensed under the MIT license.
package com.cosmotech.common.id

import java.lang.IllegalArgumentException
import kotlin.test.assertFalse
import kotlin.test.assertNotEquals
import kotlin.test.assertTrue
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows

class CsmIdGeneratorTests {
@Test
fun `generate with blank scope`() {
assertThrows<IllegalArgumentException> { generateId("") }
assertThrows<IllegalArgumentException> { generateId(" ") }
}

@Test
fun `generate with no prepend prefix`() {
val hashid = generateId("fake_scope")
assertFalse { hashid.isBlank() }
assertTrue { hashid.startsWith("f-", ignoreCase = false) }
assertFalse { hashid.substringAfter("f-", missingDelimiterValue = "").isBlank() }
}

@Test
fun `generate with custom prepend prefix`() {
val hashid = generateId("test_scope", prependPrefix = "my-custom-prefix-")
assertFalse { hashid.isBlank() }
assertTrue { hashid.startsWith("my-custom-prefix-", ignoreCase = false) }
assertFalse { hashid.substringAfter("my-custom-prefix-").isBlank() }
}

@Test
fun `2 generations within a same scope do not return the same ID`() {
val hashid1 = generateId("test_scope")
val hashid2 = generateId("test_scope")
assertFalse { hashid1.isBlank() }
assertTrue { hashid1.startsWith("t-", ignoreCase = false) }
assertFalse { hashid2.isBlank() }
assertTrue { hashid2.startsWith("t-", ignoreCase = false) }
assertNotEquals(hashid1, hashid2)
}

@Test
fun `2 generations within different scopes do not return the same ID`() {
val hashid1 = generateId("test scope")
val hashid2 = generateId("another scope")
assertFalse { hashid1.isBlank() }
assertTrue { hashid1.startsWith("t-", ignoreCase = false) }
assertFalse { hashid2.isBlank() }
assertTrue { hashid2.startsWith("a-", ignoreCase = false) }
assertNotEquals(hashid1, hashid2)
}
}

This file was deleted.

This file was deleted.

2 changes: 0 additions & 2 deletions config/application-dev.sample.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ csm:
base-path: /
base-url: "[fill-this-value]" # e.g for running it locally http://localhost:8080
version: latest
id-generator:
type: hashid
event-publisher:
type: in_process
allowedTenants:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ csm:
base-path: /
base-url: "http://fake_url:8080"
version: latest
id-generator:
type: hashid
event-publisher:
type: in_process
upload:
Expand Down
Loading