apicurio-registry icon indicating copy to clipboard operation
apicurio-registry copied to clipboard

ccompat/v6 : delete artifact version provoke inconsistent behavior

Open mpumd opened this issue 2 years ago • 3 comments

Hi all,

With ccompat/v6 api, the deletion of a specific version of an artifact works but provoke a lot of error in the registry until a global inconsistent behavior.

Here is a list of artifacts that I have in my registry :

curl https://myregistry.company.com/apis/ccompat/v6/subjects/ | jq                                                          
[ 
  "client.Market.event.MarketClosureEvent",
  "com.company.test.CacheDataRemove",
  "com.company.test.CacheDataStatus",
  "com.company.test.MarketContracts", 
  "com.company.test.MarketCreditDetails", 
  "com.company.test.MarketExposures", 
  "com.company.test.MarketLinks", 
  "com.company.test.MarketOverdraftFacilities", 
  "com.company.mpusg.test.Pet", 
  "org.acme.kafka.quarkus.Movie", 
  "pests-avro-record" 
] 

curl https://myregistry.company.com/apis/registry/v2/groups/default/artifacts/ | jq '.artifacts[].id'
"org.acme.kafka.quarkus.Movie"
"com.company.test.CacheDataRemove"
"com.company.test.CacheDataStatus"
"com.company.test.MarketContracts"
"com.company.test.MarketCreditDetails"
"com.company.test.MarketExposures"
"com.company.test.MarketLinks"
"com.company.test.MarketOverdraftFacilities"
"com.company.mpusg.test.Pet"
"client.Market.event.MarketClosureEvent"
"pests-avro-record"

By the way, the order of each artifact's list are different between ccompat/v6 and registry/v2. Doesn't matter I guess.

Take com.company.mpusg.test.Pet like an example. I have some versions for this artifacts.

curl https://myregistry.company.com/apis/ccompat/v6/subjects/com.company.mpusg.test.Pet/versions | jq
[ 
  1, 
  2, 
  3, 
  7, 
  8 
] 

curl https://myregistry.company.com/apis/registry/v2/groups/default/artifacts/com.company.mpusg.test.Pet/versions | jq '.versions[].version' 
"1"
"2"
"3"
"8"
"7"

The latest version of this artifact is available.

curl https://myregistry.company.com/apis/ccompat/v6/subjects/com.company.mpusg.test.Pet/versions/latest | jq
{ 
  "id": 63,
  "subject": "com.company.mpusg.test.Pet", 
  "version": 5,
  "schema": "{\"type\":\"record\",\"name\":\"Pet\",\"namespace\":\"com.company.mpusg.test\",\"fields\"
:[{\"name\":\"name7\",\"type\":\"string\"},{\"name\":\"holderId\",\"type\":[\"int\",\"null\"]},{\
"name\":\"type\",\"type\":[\"string\",\"null\"]},{\"name\":\"color\",\"type\":[\"string\",\"null\
"]},{\"name\":\"age\",\"type\":[\"int\",\"null\"]}]}"
}

curl https://myregistry.company.com/apis/registry/v2/groups/default/artifacts/com.company.mpusg.test.Pet | jq
{
  "type": "record",
  "name": "Pet",
  "namespace": "com.company.mpusg.test",
  "fields": [
    {
      "name": "name7",
      "type": "string"
    },
    {
      "name": "holderId",
      "type": [
        "int",
        "null"
      ]
    },
    {
      "name": "type",
      "type": [
        "string",
        "null"
      ]
    },
    {
      "name": "color",
      "type": [
        "string",
        "null"
      ]
    },
    {
      "name": "age",
      "type": [
        "int",
        "null"
      ]
    }
  ]
}

So I delete the version 3 : curl -X DELETE https://myregistry.company.com/apis/ccompat/v6/subjects/com.company.mpusg.test.Pet/versions/3

The version doesn't exist anymore.

curl https://myregistry.company.com/apis/ccompat/v6/subjects/com.company.mpusg.test.Pet/versions | jq 
[ 
  1,
  2,
  7,
  8 
] 

I see again my artifact in the list of ccompat/v6. That's ok.

curl https://myregistry.company.com/apis/ccompat/v6/subjects | jq 
[ 
 "client.Market.event.MarketClosureEvent", 
 "client.Market.event.MarketRef", 
 "com.company.test.CacheDataRemove", 
 "com.company.test.CacheDataStatus", 
 "com.company.test.MarketContracts", 
 "com.company.test.MarketCreditDetails", 
 "com.company.test.MarketExposures", 
 "com.company.test.MarketLinks", 
 "com.company.test.MarketOverdraftFacilities", 
 "com.company.jevolo.avro.Pet", 
 "com.company.mpusg.test.Pet", 
 "org.acme.kafka.quarkus.Movie", 
 "pests-avro-record" 
] 

In registry/v2, the artifact disappears. Why ?

curl https://myregistry.company.com/apis/registry/v2/groups/default/artifacts/ | jq '.artifacts[].id' 
"org.acme.kafka.quarkus.Movie" 
"com.company.test.CacheDataRemove" 
"com.company.test.CacheDataStatus" 
"com.company.test.MarketContracts" 
"com.company.test.MarketCreditDetails" 
"com.company.test.MarketExposures" 
"com.company.test.MarketLinks" 
"com.company.test.MarketOverdraftFacilities" 
"com.company.jevolo.avro.Pet" 
"client.Market.event.MarketClosureEvent" 
"client.Market.event.MarketRef" 
"pests-avro-record" 

The latest version can't be found.

curl https://myregistry.company.com/apis/ccompat/v6/subjects/com.company.mpusg.test.Pet/versions/latest | jq 
{ 
 "message": "No artifact with ID 'com.company.mpusg.test.Pet' in group 'null' was found.", 
 "error_code": 40401 
} 

curl https://myregistry.company.com/apis/registry/v2/groups/default/artifacts/com.company.mpusg.test.Pet | jq
{
  "message": "No artifact with ID 'com.company.mpusg.test.Pet' in group 'null' was found.",
  "error_code": 404,
  "detail": "io.apicurio.registry.storage.ArtifactNotFoundException: No artifact with ID 'com.company.mpusg.test.Pet' in group 'null' was found.\n\tat io.apicurio.registry.storage.impl.sql.AbstractSqlRegistryStorage.getLatestArtifactMetaDataInternal(AbstractSqlRegistryStorage.java:1163)\n\tat io.apicurio.registry.storage.impl.sql.AbstractSqlRegistryStorage.getArtifactMetaData(AbstractSqlRegistryStorage.java:1143)\n\tat io.apicurio.registry.storage.impl.kafkasql.sql.KafkaSqlStore_Subclass.getArtifactMetaData$$superaccessor170(KafkaSqlStore_Subclass.zig:29367)\n\tat io.apicurio.registry.storage.impl.kafkasql.sql.KafkaSqlStore_Subclass$$function$$170.apply(KafkaSqlStore_Subclass$$function$$170.zig:41)\n\tat io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)\n\tat io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorBase.invokeInOurTx(TransactionalInterceptorBase.java:127)\n\tat io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorBase.invokeInOurTx(TransactionalInterceptorBase.java:100)\n\tat io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorRequired.doIntercept(TransactionalInterceptorRequired.java:32)\n\tat io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorBase.intercept(TransactionalInterceptorBase.java:53)\n\tat io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorRequired.intercept(TransactionalInterceptorRequired.java:26)\n\tat io.quarkus.narayana.jta.runtime.interceptor.TransactionalInterceptorRequired_Bean.intercept(TransactionalInterceptorRequired_Bean.zig:340)\n\tat io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)\n\tat io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:50)\n\tat io.apicurio.registry.logging.LoggingInterceptor.logMethodEntry(LoggingInterceptor.java:55)\n\tat io.apicurio.registry.logging.LoggingInterceptor_Bean.intercept(LoggingInterceptor_Bean.zig:275)\n\tat io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)\n\tat io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)\n\tat io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)\n\tat io.apicurio.registry.storage.impl.kafkasql.sql.KafkaSqlStore_Subclass.getArtifactMetaData(KafkaSqlStore_Subclass.zig:29304)\n\tat io.apicurio.registry.storage.impl.kafkasql.sql.KafkaSqlStore_ClientProxy.getArtifactMetaData(KafkaSqlStore_ClientProxy.zig:2686)\n\tat io.apicurio.registry.storage.impl.kafkasql.KafkaSqlRegistryStorage.getArtifactMetaData(KafkaSqlRegistryStorage.java:511)\n\tat io.apicurio.registry.storage.impl.kafkasql.KafkaSqlRegistryStorage_Subclass.getArtifactMetaData$$superaccessor47(KafkaSqlRegistryStorage_Subclass.zig:9578)\n\tat io.apicurio.registry.storage.impl.kafkasql.KafkaSqlRegistryStorage_Subclass$$function$$47.apply(KafkaSqlRegistryStorage_Subclass$$function$$47.zig:41)\n\tat io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)\n\tat io.smallrye.metrics.interceptors.CountedInterceptor.countedCallable(CountedInterceptor.java:95)\n\tat io.smallrye.metrics.interceptors.CountedInterceptor.countedMethod(CountedInterceptor.java:70)\n\tat io.smallrye.metrics.interceptors.CountedInterceptor_Bean.intercept(CountedInterceptor_Bean.zig:366)\n\tat io.quarkus.arc.impl.InitializedInterceptor.intercept(InitializedInterceptor.java:79)\n\tat io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)\n\tat io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:50)\n\tat io.smallrye.metrics.interceptors.TimedInterceptor.timedCallable(TimedInterceptor.java:95)\n\tat io.smallrye.metrics.interceptors.TimedInterceptor.timedMethod(TimedInterceptor.java:70)\n\tat io.smallrye.metrics.interceptors.TimedInterceptor_Bean.intercept(TimedInterceptor_Bean.zig:366)\n\tat io.quarkus.arc.impl.InitializedInterceptor.intercept(InitializedInterceptor.java:79)\n\tat io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)\n\tat io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:50)\n\tat io.smallrye.metrics.interceptors.ConcurrentGaugeInterceptor.concurrentCallable(ConcurrentGaugeInterceptor.java:96)\n\tat io.smallrye.metrics.interceptors.ConcurrentGaugeInterceptor.countedMethod(ConcurrentGaugeInterceptor.java:69)\n\tat io.smallrye.metrics.interceptors.ConcurrentGaugeInterceptor_Bean.intercept(ConcurrentGaugeInterceptor_Bean.zig:366)\n\tat io.quarkus.arc.impl.InitializedInterceptor.intercept(InitializedInterceptor.java:79)\n\tat io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)\n\tat io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:50)\n\tat io.apicurio.registry.metrics.PersistenceExceptionLivenessInterceptor.intercept(PersistenceExceptionLivenessInterceptor.java:25)\n\tat io.apicurio.registry.metrics.PersistenceExceptionLivenessInterceptor_Bean.intercept(PersistenceExceptionLivenessInterceptor_Bean.zig:378)\n\tat io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)\n\tat io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:50)\n\tat io.apicurio.registry.metrics.PersistenceTimeoutReadinessInterceptor.intercept(PersistenceTimeoutReadinessInterceptor.java:27)\n\tat io.apicurio.registry.metrics.PersistenceTimeoutReadinessInterceptor_Bean.intercept(PersistenceTimeoutReadinessInterceptor_Bean.zig:327)\n\tat io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)\n\tat io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:50)\n\tat io.apicurio.registry.logging.LoggingInterceptor.logMethodEntry(LoggingInterceptor.java:55)\n\tat io.apicurio.registry.logging.LoggingInterceptor_Bean.intercept(LoggingInterceptor_Bean.zig:275)\n\tat io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)\n\tat io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)\n\tat io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)\n\tat io.apicurio.registry.storage.impl.kafkasql.KafkaSqlRegistryStorage_Subclass.getArtifactMetaData(KafkaSqlRegistryStorage_Subclass.zig:9515)\n\tat io.apicurio.registry.storage.impl.kafkasql.KafkaSqlRegistryStorage_ClientProxy.getArtifactMetaData(KafkaSqlRegistryStorage_ClientProxy.zig:1622)\n\tat io.apicurio.registry.storage.RegistryStorageProducer_ProducerMethod_realImpl_cf1c876861dd1c25dca504d30a12bfedeafd47bd_ClientProxy.getArtifactMetaData(RegistryStorageProducer_ProducerMethod_realImpl_cf1c876861dd1c25dca504d30a12bfedeafd47bd_ClientProxy.zig:845)\n\tat io.apicurio.registry.rest.v2.GroupsResourceImpl.getLatestArtifact(GroupsResourceImpl.java:137)\n\tat io.apicurio.registry.rest.v2.GroupsResourceImpl_Subclass.getLatestArtifact$$superaccessor34(GroupsResourceImpl_Subclass.zig:6384)\n\tat io.apicurio.registry.rest.v2.GroupsResourceImpl_Subclass$$function$$34.apply(GroupsResourceImpl_Subclass$$function$$34.zig:41)\n\tat io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)\n\tat io.smallrye.metrics.interceptors.CountedInterceptor.countedCallable(CountedInterceptor.java:95)\n\tat io.smallrye.metrics.interceptors.CountedInterceptor.countedMethod(CountedInterceptor.java:70)\n\tat io.smallrye.metrics.interceptors.CountedInterceptor_Bean.intercept(CountedInterceptor_Bean.zig:366)\n\tat io.quarkus.arc.impl.InitializedInterceptor.intercept(InitializedInterceptor.java:79)\n\tat io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)\n\tat io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:50)\n\tat io.smallrye.metrics.interceptors.TimedInterceptor.timedCallable(TimedInterceptor.java:95)\n\tat io.smallrye.metrics.interceptors.TimedInterceptor.timedMethod(TimedInterceptor.java:70)\n\tat io.smallrye.metrics.interceptors.TimedInterceptor_Bean.intercept(TimedInterceptor_Bean.zig:366)\n\tat io.quarkus.arc.impl.InitializedInterceptor.intercept(InitializedInterceptor.java:79)\n\tat io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)\n\tat io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:50)\n\tat io.smallrye.metrics.interceptors.ConcurrentGaugeInterceptor.concurrentCallable(ConcurrentGaugeInterceptor.java:96)\n\tat io.smallrye.metrics.interceptors.ConcurrentGaugeInterceptor.countedMethod(ConcurrentGaugeInterceptor.java:69)\n\tat io.smallrye.metrics.interceptors.ConcurrentGaugeInterceptor_Bean.intercept(ConcurrentGaugeInterceptor_Bean.zig:366)\n\tat io.quarkus.arc.impl.InitializedInterceptor.intercept(InitializedInterceptor.java:79)\n\tat io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)\n\tat io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:50)\n\tat io.apicurio.registry.metrics.RestMetricsInterceptor.intercept(RestMetricsInterceptor.java:82)\n\tat io.apicurio.registry.metrics.RestMetricsInterceptor_Bean.intercept(RestMetricsInterceptor_Bean.zig:327)\n\tat io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)\n\tat io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:50)\n\tat io.apicurio.registry.logging.LoggingInterceptor.logMethodEntry(LoggingInterceptor.java:55)\n\tat io.apicurio.registry.logging.LoggingInterceptor_Bean.intercept(LoggingInterceptor_Bean.zig:275)\n\tat io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)\n\tat io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)\n\tat io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)\n\tat io.apicurio.registry.rest.v2.GroupsResourceImpl_Subclass.getLatestArtifact(GroupsResourceImpl_Subclass.zig:6339)\n\tat io.apicurio.registry.rest.v2.GroupsResourceImpl_ClientProxy.getLatestArtifact(GroupsResourceImpl_ClientProxy.zig:1001)\n\tat jdk.internal.reflect.GeneratedMethodAccessor162.invoke(Unknown Source)\n\tat java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n\tat java.base/java.lang.reflect.Method.invoke(Method.java:566)\n\tat org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:170)\n\tat org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:130)\n\tat org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:660)\n\tat org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:524)\n\tat org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$2(ResourceMethodInvoker.java:474)\n\tat org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)\n\tat org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:476)\n\tat org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:434)\n\tat org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:408)\n\tat org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:69)\n\tat org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:492)\n\tat org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:261)\n\tat org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:161)\n\tat org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)\n\tat org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:164)\n\tat org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:247)\n\tat org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:249)\n\tat io.quarkus.resteasy.runtime.ResteasyFilter$ResteasyResponseWrapper.service(ResteasyFilter.java:70)\n\tat io.quarkus.resteasy.runtime.ResteasyFilter$ResteasyResponseWrapper.sendError(ResteasyFilter.java:76)\n\tat io.undertow.servlet.handlers.DefaultServlet.doGet(DefaultServlet.java:172)\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:503)\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:590)\n\tat io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)\n\tat io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)\n\tat io.quarkus.resteasy.runtime.ResteasyFilter.doFilter(ResteasyFilter.java:31)\n\tat io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)\n\tat io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)\n\tat io.apicurio.registry.ui.servlets.ResourceCacheControlFilter.doFilter(ResourceCacheControlFilter.java:83)\n\tat io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)\n\tat io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)\n\tat io.apicurio.registry.rest.RegistryApplicationServletFilter.doFilter(RegistryApplicationServletFilter.java:113)\n\tat io.apicurio.registry.rest.RegistryApplicationServletFilter_ClientProxy.doFilter(RegistryApplicationServletFilter_ClientProxy.zig:225)\n\tat io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)\n\tat io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)\n\tat io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)\n\tat io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:63)\n\tat io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)\n\tat io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)\n\tat io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:67)\n\tat io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:133)\n\tat io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)\n\tat io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)\n\tat io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)\n\tat io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:65)\n\tat io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)\n\tat io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)\n\tat io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)\n\tat io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)\n\tat io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)\n\tat io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)\n\tat io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:247)\n\tat io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:56)\n\tat io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:111)\n\tat io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:108)\n\tat io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)\n\tat io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)\n\tat io.quarkus.undertow.runtime.UndertowDeploymentRecorder$9$1.call(UndertowDeploymentRecorder.java:574)\n\tat io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:227)\n\tat io.undertow.servlet.handlers.ServletInitialHandler.handleRequest(ServletInitialHandler.java:152)\n\tat io.quarkus.undertow.runtime.UndertowDeploymentRecorder$1.handleRequest(UndertowDeploymentRecorder.java:117)\n\tat io.undertow.server.Connectors.executeRootHandler(Connectors.java:290)\n\tat io.undertow.server.DefaultExchangeHandler.handle(DefaultExchangeHandler.java:18)\n\tat io.quarkus.undertow.runtime.UndertowDeploymentRecorder$5$1.run(UndertowDeploymentRecorder.java:400)\n\tat java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)\n\tat java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)\n\tat org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2415)\n\tat org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1452)\n\tat org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)\n\tat org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)\n\tat java.base/java.lang.Thread.run(Thread.java:829)\n\tat org.jboss.threads.JBossThread.run(JBossThread.java:501)\n",
  "name": "ArtifactNotFoundException"
}

I lose the artifact inside the UI of the registry related to the lose inside the registry/v2 I guess.

This deletion endpoint doesn't exist on registry/v2 side. What do you suggest about the lifecycle of an artifact ? DISABLED a version instead of delete ? Please could you fix the problems beget by deletion ?

Thanks for your investigations.

Good luck !

mpumd avatar Sep 23 '22 07:09 mpumd

hi @mpusg I'm trying to reproduce this but no luck yet. Do you have steps that reproduce this issue reliably, or does it happen randomly? Can you let me know which Registry version and persistence option are you using? Are there any interesting logs?

jsenko avatar Sep 26 '22 09:09 jsenko

After additional investigation, I think the issue is related to this code https://github.com/Apicurio/apicurio-registry/blob/main/app/src/main/java/io/apicurio/registry/storage/impl/sql/AbstractSqlRegistryStorage.java#L1740 . When deleting a subject version, Registry has to determine what the next latest version is (e.g. in case the latest version was deleted). It first sets the latest version to null, and then attempts to find a version with the greatest globalID to replace it. It seems, however, that in some cases the latest version column may remain null. This may explain the latest artifact disappearing. However I was only able to force this behavior artificially. I can try to improve the code, but I wouldn't be sure I fixed your issue without a reliable reproducer.

jsenko avatar Sep 26 '22 10:09 jsenko

Hi @Jsenko,

Thanks for your answer. I use the version 2.0.2.Final-redhat-00001 of apicurio registry by redhat. This registry is manage by an operator installed in openshift which is in version 2.0.5+0.1648813064.p

I can reproduce this issue reliably. I don't have extract database to provide you unfortunately.

Just follow my case at below.

Considere an artifact named com.company.Pet with 3 versions numbered 1,2,3. You could have also some artifacts in the registry.

  1. You can see the same version numbers of each apis.
GET /apis/registry/v2/groups/default/artifacts/com.company.Pet/versions  // with a default group. Set whatever you want.
GET /apis/ccompat/v6/subjects/com.company.Pet/versions | jq.version[].version
[
  1,
  2,
  3 
] 
  1. you can see our artifact when you list them with apis.
  2. you can get the schema for the version 2 (It's the version that I will delete) and the latest.
  3. Delete the version 2
GET /apis/ccompat/v6/subjects/com.company.Pet/versions
GET /apis/registry/v2/groups/default/artifacts/com.company.Pet/versions | jq.version[].version
[
  1, 
  3                                                                                             
]                                                                                               

=> effect

  • You loose our artifact when you list them by /apis/registry/v2/groups/default/artifacts. ccompat/v6 works.
  • latest version endpoint doesn't works /apis/ccompat/v6/subjects/com.company.Pet/versions/latest or /apis/registry/v2/groups/default/artifacts/com.company.Pet

What is a great reproducer for you ?

mpumd avatar Oct 12 '22 13:10 mpumd

Hi @jsenko,

Any news on the issue ? Thanks.

mpumd avatar Oct 24 '22 13:10 mpumd

any news on this?

vsevel avatar Mar 15 '23 08:03 vsevel

I think @jsenko had a PR that attempted to address this issue. There were some issues with it and it wasn't merged. Only because we didn't have the bandwidth to finish it up. We'll try to bring that back from the dead...

EricWittmann avatar Mar 22 '23 11:03 EricWittmann