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

New function not based on list endpoint #255

Merged
merged 1 commit into from
Aug 20, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ final case class Resolver[F[_]](repos: List[Registry], cache: Option[ResolverCac
private[client] val allRepos: NonEmptyList[Registry] =
NonEmptyList[Registry](Registry.EmbeddedRegistry, repos)

private val allIgluCentral: Set[String] = repos.collect {
case Registry.Http(config, connection)
if connection.uri.getHost.matches(""".*\biglucentral\b.*""") =>
config.name
}.toSet

/**
* Tries to find the given schema in any of the provided repository refs
* If any of repositories gives non-non-found error, lookup will retried
Expand Down Expand Up @@ -181,6 +187,71 @@ final case class Resolver[F[_]](repos: List[Registry], cache: Option[ResolverCac
): F[Either[ResolutionError, Json]] =
lookupSchemaResult(schemaKey).map(_.map(_.value.schema))

/**
* If Iglu Central or any of its mirrors doesn't have a schema,
* it should be considered NotFound, even if one of them returned an error.
*/
private[resolver] def isNotFound(error: ResolutionError): Boolean = {
val (igluCentral, custom) = error.value.partition { case (repo, _) =>
allIgluCentral.contains(repo)
}
(igluCentral.isEmpty || igluCentral.values.exists(
_.errors.exists(_ == RegistryError.NotFound)
)) && custom.values.flatMap(_.errors).forall(_ == RegistryError.NotFound)
}

/**
* Looks up all the schemas with the same model until `maxSchemaKey`.
* For the schemas of previous revisions, it starts with addition = 0
* and increments it until a NotFound.
*
* @param maxSchemaKey The SchemaKey until which schemas of the same model should get returned
* @return All the schemas if all went well, [[Resolver.SchemaResolutionError]] with the first error that happened
* while looking up the schemas if something went wrong.
*/
def lookupSchemasUntil(
maxSchemaKey: SchemaKey
)(implicit
F: Monad[F],
L: RegistryLookup[F],
C: Clock[F]
): F[Either[SchemaResolutionError, NonEmptyList[SelfDescribingSchema[Json]]]] = {
def go(
current: SchemaVer.Full,
acc: List[SelfDescribingSchema[Json]]
): F[Either[SchemaResolutionError, NonEmptyList[SelfDescribingSchema[Json]]]] = {
val currentSchemaKey = maxSchemaKey.copy(version = current)
lookupSchema(currentSchemaKey).flatMap {
case Left(e) =>
if (current.addition === 0)
Monad[F].pure(Left(SchemaResolutionError(currentSchemaKey, e)))
else if (current.revision < maxSchemaKey.version.revision && isNotFound(e))
go(current.copy(revision = current.revision + 1, addition = 0), acc)
else
Monad[F].pure(Left(SchemaResolutionError(currentSchemaKey, e)))
case Right(json) =>
if (current.revision < maxSchemaKey.version.revision)
go(
current.copy(addition = current.addition + 1),
SelfDescribingSchema(SchemaMap(currentSchemaKey), json) :: acc
)
else if (current.addition < maxSchemaKey.version.addition)
go(
current.copy(addition = current.addition + 1),
SelfDescribingSchema(SchemaMap(currentSchemaKey), json) :: acc
)
else
Monad[F].pure(
Right(
NonEmptyList(SelfDescribingSchema(SchemaMap(currentSchemaKey), json), acc).reverse
)
)
}
}

go(SchemaVer.Full(maxSchemaKey.version.model, 0, 0), Nil)
benjben marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Get list of available schemas for particular vendor and name part
* Server supposed to return them in proper order
Expand Down Expand Up @@ -389,6 +460,8 @@ object Resolver {
*/
case class SchemaItem(schema: Json, supersededBy: SupersededBy)

case class SchemaResolutionError(schemaKey: SchemaKey, error: ResolutionError)

/** The result of doing a lookup with the resolver, carrying information on whether the cache was used */
sealed trait ResolverResult[+K, +A] {
def value: A
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"$schema": "http://iglucentral.com/schemas/com.snowplowanalytics.self-desc/schema/jsonschema/1-0-0#",
"description": "Schema to test lookupSchemasUntil function",
"self": {
"vendor": "com.snowplowanalytics",
"name": "lookup-schemas-until",
"format": "jsonschema",
"version": "3-1-0"
},
"type": "object",
"properties": {
"field___1": {
"type": "string"
},
"field___2": {
"type": ["string", "null"]
}
},
"required": [
"field___1"
],
"additionalProperties": false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"$schema": "http://iglucentral.com/schemas/com.snowplowanalytics.self-desc/schema/jsonschema/1-0-0#",
"description": "Schema to test lookupSchemasUntil function",
"self": {
"vendor": "com.snowplowanalytics",
"name": "lookup-schemas-until",
"format": "jsonschema",
"version": "1-0-0"
},
"type": "object",
"properties": {
"field_1": {
"type": "string"
}
},
"required": [
"field_1"
],
"additionalProperties": false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"$schema": "http://iglucentral.com/schemas/com.snowplowanalytics.self-desc/schema/jsonschema/1-0-0#",
"description": "Schema to test lookupSchemasUntil function",
"self": {
"vendor": "com.snowplowanalytics",
"name": "lookup-schemas-until",
"format": "jsonschema",
"version": "1-1-0"
},
"type": "object",
"properties": {
"field_1": {
"type": "string"
},
"field_2": {
"type": ["string", "null"]
}
},
"required": [
"field_1"
],
"additionalProperties": false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"$schema": "http://iglucentral.com/schemas/com.snowplowanalytics.self-desc/schema/jsonschema/1-0-0#",
"description": "Schema to test lookupSchemasUntil function",
"self": {
"vendor": "com.snowplowanalytics",
"name": "lookup-schemas-until",
"format": "jsonschema",
"version": "1-1-1"
},
"type": "object",
"properties": {
"field_1": {
"type": "string"
},
"field_2": {
"type": ["string", "null"]
},
"field_3": {
"type": ["string", "null"]
}
},
"required": [
"field_1"
],
"additionalProperties": false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"$schema": "http://iglucentral.com/schemas/com.snowplowanalytics.self-desc/schema/jsonschema/1-0-0#",
"description": "Schema to test lookupSchemasUntil function",
"self": {
"vendor": "com.snowplowanalytics",
"name": "lookup-schemas-until",
"format": "jsonschema",
"version": "1-1-2"
},
"type": "object",
"properties": {
"field_1": {
"type": "string"
},
"field_2": {
"type": ["string", "null"]
},
"field_3": {
"type": ["string", "null"]
},
"field_4": {
"type": ["string", "null"]
}
},
"required": [
"field_1"
],
"additionalProperties": false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"$schema": "http://iglucentral.com/schemas/com.snowplowanalytics.self-desc/schema/jsonschema/1-0-0#",
"description": "Schema to test lookupSchemasUntil function",
"self": {
"vendor": "com.snowplowanalytics",
"name": "lookup-schemas-until",
"format": "jsonschema",
"version": "1-2-0"
},
"type": "object",
"properties": {
"field_1": {
"type": "string"
},
"field_2": {
"type": ["string", "null"]
},
"field_3": {
"type": ["string", "null"]
},
"field_4": {
"type": ["string", "null"]
},
"field_5": {
"type": ["string", "null"]
}
},
"required": [
"field_1"
],
"additionalProperties": false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"$schema": "http://iglucentral.com/schemas/com.snowplowanalytics.self-desc/schema/jsonschema/1-0-0#",
"description": "Schema to test lookupSchemasUntil function",
"self": {
"vendor": "com.snowplowanalytics",
"name": "lookup-schemas-until",
"format": "jsonschema",
"version": "1-2-1"
},
"type": "object",
"properties": {
"field_1": {
"type": "string"
},
"field_2": {
"type": ["string", "null"]
},
"field_3": {
"type": ["string", "null"]
},
"field_4": {
"type": ["string", "null"]
},
"field_5": {
"type": ["string", "null"]
},
"field_6": {
"type": ["string", "null"]
}
},
"required": [
"field_1"
],
"additionalProperties": false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"$schema": "http://iglucentral.com/schemas/com.snowplowanalytics.self-desc/schema/jsonschema/1-0-0#",
"description": "Schema to test lookupSchemasUntil function",
"self": {
"vendor": "com.snowplowanalytics",
"name": "lookup-schemas-until",
"format": "jsonschema",
"version": "1-2-2"
},
"type": "object",
"properties": {
"field_1": {
"type": "string"
},
"field_2": {
"type": ["string", "null"]
},
"field_3": {
"type": ["string", "null"]
},
"field_4": {
"type": ["string", "null"]
},
"field_5": {
"type": ["string", "null"]
},
"field_6": {
"type": ["string", "null"]
},
"field_7": {
"type": ["string", "null"]
}
},
"required": [
"field_1"
],
"additionalProperties": false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"$schema": "http://iglucentral.com/schemas/com.snowplowanalytics.self-desc/schema/jsonschema/1-0-0#",
"description": "Invalid schema to test lookupSchemasUntil function - Misses comma after properties",
"self": {
"vendor": "com.snowplowanalytics",
"name": "lookup-schemas-until",
"format": "jsonschema",
"version": "1-3-0"
},
"type": "object",
"properties": {
"field_1": {
"type": "string"
},
"field_2": {
"type": ["string", "null"]
},
"field_3": {
"type": ["string", "null"]
},
"field_4": {
"type": ["string", "null"]
},
"field_5": {
"type": ["string", "null"]
},
"field_6": {
"type": ["string", "null"]
},
"field_7": {
"type": ["string", "null"]
},
"field_8": {
"type": ["string", "null"]
}
}
"required": [
"field_1"
],
"additionalProperties": false
}
Loading
Loading