Uploaded image for project: 'Apache NiFi'
  1. Apache NiFi
  2. NIFI-12918

Stateless NiFi NullPointerException on versioned PGs

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • None
    • 1.26.0, 2.0.0-M3
    • NiFi Stateless
    • None

    Description

      If you create a process group and commit that to version control, and then add a sub-process group under that one and commit that to its own version control, it will throw a NullPointerException:

      NOTE: This error only occurs for stateless nifi processing.

      2024-03-15T12:25:38.565156967Z 2024-03-15 12:25:38,564 INFO [main] o.a.nifi.groups.StandardProcessGroup StandardProcessGroup[identifier=9688e64b-3f4a-3668-81b9-e25d9ea61454,name=Sub Group] added to StandardProcessGroup[identifier=stateless-flow,name=Test Flow]
      2024-03-15T12:25:38.570693223Z Exception in thread "main" java.lang.NullPointerException: Registry ID must be specified
      	at java.base/java.util.Objects.requireNonNull(Unknown Source)
      2024-03-15T12:25:38.570722016Z 	at org.apache.nifi.registry.flow.StandardVersionControlInformation$Builder.build(StandardVersionControlInformation.java:134)
      2024-03-15T12:25:38.570725111Z 	at org.apache.nifi.flow.synchronization.StandardVersionedComponentSynchronizer.synchronize(StandardVersionedComponentSynchronizer.java:354)
      2024-03-15T12:25:38.570729455Z 	at org.apache.nifi.flow.synchronization.StandardVersionedComponentSynchronizer.addProcessGroup(StandardVersionedComponentSynchronizer.java:1185)
      	at org.apache.nifi.flow.synchronization.StandardVersionedComponentSynchronizer.synchronizeChildGroups(StandardVersionedComponentSynchronizer.java:528)
      2024-03-15T12:25:38.573083029Z 	at org.apache.nifi.flow.synchronization.StandardVersionedComponentSynchronizer.synchronize(StandardVersionedComponentSynchronizer.java:426)
      2024-03-15T12:25:38.573086447Z 	at org.apache.nifi.flow.synchronization.StandardVersionedComponentSynchronizer.lambda$synchronize$0(StandardVersionedComponentSynchronizer.java:265)
      2024-03-15T12:25:38.573092747Z 	at org.apache.nifi.controller.flow.AbstractFlowManager.withParameterContextResolution(AbstractFlowManager.java:551)
      2024-03-15T12:25:38.573095677Z 	at org.apache.nifi.flow.synchronization.StandardVersionedComponentSynchronizer.synchronize(StandardVersionedComponentSynchronizer.java:260)
      2024-03-15T12:25:38.573098999Z 	at org.apache.nifi.groups.StandardProcessGroup.synchronizeFlow(StandardProcessGroup.java:3977)
      	at org.apache.nifi.groups.StandardProcessGroup.updateFlow(StandardProcessGroup.java:3957)
      	at org.apache.nifi.stateless.engine.StandardStatelessEngine.createFlow(StandardStatelessEngine.java:180)
      2024-03-15T12:25:38.573108177Z 	at org.apache.nifi.stateless.flow.StandardStatelessDataflowFactory.createDataflow(StandardStatelessDataflowFactory.java:243)
      	at org.apache.nifi.stateless.bootstrap.StatelessBootstrap.createDataflow(StatelessBootstrap.java:73) 

      When stepping through the debugger, it appears the "registryId" property is null. The JerseyClient call is supposed to map the response from registry to the proper class, but registryId is never set:

      java.lang.Thread.State: RUNNABLE
      	  at org.apache.nifi.flow.VersionedProcessGroup.setVersionedFlowCoordinates(VersionedProcessGroup.java:150)
      	  at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Unknown Source:-1)
      	  at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source:-1)
      	  at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source:-1)
      	  at java.lang.reflect.Method.invoke(Unknown Source:-1)
      	  at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:141)
      	  at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:314)
      	  at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
      	  at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer._deserializeFromArray(CollectionDeserializer.java:359)
      	  at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:244)
      	  at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:28)
      	  at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
      	  at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:314)
      	  at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
      	  at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
      	  at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:314)
      	  at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
      	  at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:323)
      	  at com.fasterxml.jackson.databind.ObjectReader._bind(ObjectReader.java:2079)
      	  at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1229)
      	  at org.glassfish.jersey.jackson.internal.jackson.jaxrs.base.ProviderBase.readFrom(ProviderBase.java:829)
      	  at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:233)
      	  at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:212)
      	  at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:132)
      	  at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1072)
      	  at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:919)
      	  at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:853)
      	  at org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:298)
      	  at org.glassfish.jersey.client.JerseyInvocation.translate(JerseyInvocation.java:742)
      	  at org.glassfish.jersey.client.JerseyInvocation.lambda$invoke$1(JerseyInvocation.java:675)
      	  at org.glassfish.jersey.client.JerseyInvocation$$Lambda$294.273041802.call(Unknown Source:-1)
      	  at org.glassfish.jersey.client.JerseyInvocation.call(JerseyInvocation.java:697)
      	  at org.glassfish.jersey.client.JerseyInvocation.lambda$runInScope$3(JerseyInvocation.java:691)
      	  at org.glassfish.jersey.client.JerseyInvocation$$Lambda$295.608108604.call(Unknown Source:-1)
      	  at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
      	  at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
      	  at org.glassfish.jersey.internal.Errors.process(Errors.java:205)
      	  at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:390)
      	  at org.glassfish.jersey.client.JerseyInvocation.runInScope(JerseyInvocation.java:691)
      	  at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:674)
      	  at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:422)
      	  at org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:318)
      	  at org.apache.nifi.registry.client.impl.JerseyFlowSnapshotClient.lambda$get$1(JerseyFlowSnapshotClient.java:110)
      	  at org.apache.nifi.registry.client.impl.JerseyFlowSnapshotClient$$Lambda$191.1164622694.execute(Unknown Source:-1)
      	  at org.apache.nifi.registry.client.impl.AbstractJerseyClient.executeAction(AbstractJerseyClient.java:103)
      	  at org.apache.nifi.registry.client.impl.JerseyFlowSnapshotClient.get(JerseyFlowSnapshotClient.java:103)
      	  at org.apache.nifi.stateless.core.RegistryUtil.getFlowContents(RegistryUtil.java:113)
      	  at org.apache.nifi.stateless.core.RegistryUtil.getFlowByID(RegistryUtil.java:61)
      	  at org.apache.nifi.stateless.config.PropertiesFileFlowDefinitionParser.fetchFlowFromRegistry(PropertiesFileFlowDefinitionParser.java:603)
      	  at org.apache.nifi.stateless.config.PropertiesFileFlowDefinitionParser.fetchVersionedFlowSnapshot(PropertiesFileFlowDefinitionParser.java:541)
      	  at org.apache.nifi.stateless.config.PropertiesFileFlowDefinitionParser.parseFlowDefinition(PropertiesFileFlowDefinitionParser.java:119)
      	  at org.apache.nifi.stateless.config.PropertiesFileFlowDefinitionParser.parseFlowDefinition(PropertiesFileFlowDefinitionParser.java:106)
      	  at org.apache.nifi.stateless.bootstrap.StatelessBootstrap.parseDataflowDefinition(StatelessBootstrap.java:80)
      	  at org.apache.nifi.stateless.bootstrap.RunStatelessFlow.createDataflow(RunStatelessFlow.java:92)
      	  at org.apache.nifi.stateless.bootstrap.RunStatelessFlow.main(RunStatelessFlow.java:56) 

       

      Looking further, it appears the "storageLocation" property is actually the dependency that is used for the sub-getFlow calls. I submitted the PR to change the non-null requirement to storageLocation for this reason. The sub-call in 1.x (1.25 tested) also uses the wrong "getRegistryUrl" method, which was changed to "getStorageLocation" on the main branch. Making these two changes fixes the versioned PG bug in stateless NiFi. Ultimately, it looks like 
      VersionedFlowCoordinates are not mapped from the JerseyClient call correctly. This is not done directly from the JSON returned from the registry-api call. (I'm not sure where that's done)...but with other places showing "registryId" as "placeholder", I'm assuming this is something still in "to do" status. 

      Attachments

        Activity

          People

            slambrose Stephanie Ambrose
            slambrose Stephanie Ambrose
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Time Tracking

                Estimated:
                Original Estimate - Not Specified
                Not Specified
                Remaining:
                Remaining Estimate - 0h
                0h
                Logged:
                Time Spent - 5h 50m
                5h 50m