Expand my Community achievements bar.

SOLVED

FDM PreProcessor not getting invoked

Avatar

Level 2

Hi all,

I was going through the AEM Forms Java Docs and came across the class IPreProcessor (AEM Forms API).

The description reads

IPreProcessor is a service that is called directly before executing any operation. This can be used to do some pre-processing like authorization or request modification before the invocation of the operation

I have a form data model which uses the OOB Microsoft Odata Connector to connect to Microsft Dynamics CRM and fetch some data.

I configured an adaptive form and in one of the fields, I configured a rule to invoke the above FDM service to fetch some data.

My assumption was that if we implement the interface and register a preprocessor, it would be called before invoking the actual connector.

However, there appears to be no difference with or without a preprocessor. My registered PreProcessor doesn't seem to get called anytime.

@Component((immediate = true))
@Service((IPreProcessor.class))
public class MyPreProcessor implements IPreProcessor {

   private static final Logger LOG = LoggerFactory.getLogger(MyPreProcessor.class);

   @Override
   public void preprocess(ExecutionContext executionContext) throws DermisException {
       LOG.info("Preprocessing requested");
       LOG.info("Execution Context {}", executionContext);
       LOG.info("Execution Context arguments {}", executionContext.getArguments());
       LOG.info("Execution Context arguments valuemap {}", executionContext.getArgumentsValueMap());
       LOG.info("Execution Context auth details {}", executionContext.getAuthDetails());
       LOG.info("Execution Context configuration {}", executionContext.getConfiguration());
       LOG.info("Execution Context configuration id {}", executionContext.getConfigurationId());
       LOG.info("Execution Context entity id {}", executionContext.getEntityId());
       LOG.info("Execution Context operation id {}", executionContext.getOperationId());
       LOG.info("Execution Context query {}", executionContext.getQuery());
       LOG.info("Execution Context schema name {}", executionContext.getSchemaName());
   }

   @Override
   public boolean isSupported(String connectorName, ExecutionContext executionContext) {
   LOG.info("Checking if the preprocessing is supported");
   try {
       LOG.info("Connector Name received {}", connectorName);
       LOG.info("Execution Context {}", executionContext);
       LOG.info("Execution Context arguments {}", executionContext.getArguments());
       LOG.info("Execution Context arguments valuemap {}", executionContext.getArgumentsValueMap());
       LOG.info("Execution Context auth details {}", executionContext.getAuthDetails());
       LOG.info("Execution Context configuration {}", executionContext.getConfiguration());
       LOG.info("Execution Context configuration id {}", executionContext.getConfigurationId());
       LOG.info("Execution Context entity id {}", executionContext.getEntityId());
       LOG.info("Execution Context operation id {}", executionContext.getOperationId());
       LOG.info("Execution Context query {}", executionContext.getQuery());
       LOG.info("Execution Context schema name {}", executionContext.getSchemaName());
   } catch (DermisException e) {
       LOG.error(e.getMessage(), e);
   }
   return true;
   }

}

What is the purpose of the PreProcessor then or how do I invoke custom code before the FDM operation is performed. There appears to be no documentation anywhere.

1 Accepted Solution

Avatar

Correct answer by
Level 2

Hi all,

 

Received an update from the engineering team via daycare.

So, the right way to register the Preprocessor is to implement the PreProcessor interface but register it as an IProcessor service.

 

@component((immediate = true))
@Service((IProcessor.class))
public class MyPreProcessor implements IPreProcessor {

   private static final Logger LOG = LoggerFactory.getLogger(MyPreProcessor.class);

   //Implementation here
}
 

 

View solution in original post

8 Replies

Avatar

Employee Advisor

Hi Rakesh,

We will get back to you shortly. Khushwant Singh​ By any chance do you have any sample or documentation for the preprocessor.

Avatar

Level 2

Pre processor should be invoked if isSupporting is returning true for that particular operation.

Can you please check your service is up and running? And exception or error occur in pre processor.

Regards,
Vijay Kumar J

Avatar

Level 2

I was able to deduce that from the docs.

If you look at the sample code that I posted in the original question, the isSupported method returns true always.

But the control never reaches the isSupported method.

There are no logs that I have printed in that method nor are there any errors in the log file.

Avatar

Level 2

Can you please send the screenshot of component status in system console?

Avatar

Level 2

Here you go.

Screen Shot 2019-11-08 at 8.57.26 am.png

The only difference in the code from my original questions vs the service running in my instance is the name of the class. I've renamed it from MyPreProcessor to ACRPreProcessor. The underlying code is exactly the same.

A more fundamental question with this issue is, when would the PreProcessor actually get invoked? Would it get invoked when you have an adaptive form which invokes an FDM service? Or is it called during a different scenario? If so, what is the scenario in which the PreProcessors are invoked?

Avatar

Level 2

Can you update the class in @Service annotation to IProcess.

More specifically, kindly change

@Service((IPreProcessor.class))

to

@Service((IProcessor.class))

Avatar

Level 2

I've tried it before and there was no difference. It doesn't work.

I tried it again now and still the same.

However, the question is, how would it identify if the service is a PreProcessor or PostProcessor if you are registering it as IProcessor?

I would assume IPreProcessor would be the right service to register it as (so it can call the preprocess method in all preprocessors).

I could be wrong though.

Avatar

Correct answer by
Level 2

Hi all,

 

Received an update from the engineering team via daycare.

So, the right way to register the Preprocessor is to implement the PreProcessor interface but register it as an IProcessor service.

 

@component((immediate = true))
@Service((IProcessor.class))
public class MyPreProcessor implements IPreProcessor {

   private static final Logger LOG = LoggerFactory.getLogger(MyPreProcessor.class);

   //Implementation here
}