killbill / killbill

Open-Source Subscription Billing & Payments Platform
https://killbill.io
Apache License 2.0
4.65k stars 784 forks source link

NullPointerException in Catalog Validation when there is a phase mismatch #1945

Open reshmabidikar opened 10 months ago

reshmabidikar commented 10 months ago

The Validate Catalog XML endpoint causes a NullPointerException when there is a mismatch in the phases of the current catalog and the catalog being validated.

Steps to reproduce:

  1. Upload the monthly-no-trial catalog (has a standard-monthly plan with an EVERGREEN phase)
  2. Execute the Validate Catalog XML with the monthly-no-trial-v2 catalog (has a standard-monthly plan with a FIXEDTERM phase)
  3. This causes the following exception:
java.lang.NullPointerException: null
    at org.killbill.billing.catalog.DefaultVersionedCatalog.validatePlanShape(DefaultVersionedCatalog.java:188)
    at org.killbill.billing.catalog.DefaultVersionedCatalog.validateUniformPlanShapeAcrossVersions(DefaultVersionedCatalog.java:165)
    at org.killbill.billing.catalog.DefaultVersionedCatalog.validate(DefaultVersionedCatalog.java:151)
    at org.killbill.billing.catalog.api.user.DefaultCatalogUserApi.validateCatalogInternal(DefaultCatalogUserApi.java:235)
    at org.killbill.billing.catalog.api.user.DefaultCatalogUserApi.validateCatalog(DefaultCatalogUserApi.java:132)
    at org.killbill.billing.util.glue.KillbillApiAopModule$ProfilingMethodInterceptor$1.execute(KillbillApiAopModule.java:89)
    at org.killbill.commons.profiling.Profiling.executeWithProfiling(Profiling.java:35)
    at org.killbill.billing.util.glue.KillbillApiAopModule$ProfilingMethodInterceptor.invoke(KillbillApiAopModule.java:105)
    at org.killbill.billing.jaxrs.resources.CatalogResource.validateCatalogXml(CatalogResource.java:250)
    at org.killbill.billing.jaxrs.resources.CatalogResource_$$_jvstf09_2._d55validateCatalogXml(CatalogResource_$$_jvstf09_2.java)
    at jdk.internal.reflect.GeneratedMethodAccessor266.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.glassfish.hk2.utilities.reflection.ReflectionHelper.invoke(ReflectionHelper.java:1268)
    at org.jvnet.hk2.internal.MethodInterceptorHandler$MethodInvocationImpl.proceed(MethodInterceptorHandler.java:164)
    at org.killbill.commons.skeleton.metrics.TimedResourceInterceptor.invoke(TimedResourceInterceptor.java:70)
    at org.jvnet.hk2.internal.MethodInterceptorHandler.invoke(MethodInterceptorHandler.java:97)
    at org.killbill.billing.jaxrs.resources.CatalogResource_$$_jvstf09_2.validateCatalogXml(CatalogResource_$$_jvstf09_2.java)
    at jdk.internal.reflect.GeneratedMethodAccessor265.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:52)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:134)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:177)
    at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:176)
reshmabidikar commented 10 months ago

Debugging the code a bit, the error occurs at this line since plan.getCatalog().getEffectiveDate() is null. I believe after the catalog is cloned, the root field is null causing plan.getCatalog().getEffectiveDate() to be null (To be confirmed).

As a short-term solution, we could remove the plan.getCatalog().getEffectiveDate() field from the ValidationError object at this line.