How to store large template results?

My current customer uses a Freemarker template to produce a SOAP message. The produced result is too large to be stored inside a String variable. We do not want to change the maximum size of string variables in the database.

Is it somehow possible to set the type of an input parameter to byte[] or XML?

Hi @falko.menge,

theoretically we could store variable text in a ACT_GE_BYTEARRAY table.

Can I suggest that you use external task as a workaround? what you want basically an external storage of such a CLOB content. SO instead of putting CLOB in variable you would put it in some key\value storage and then pull it in delegate or wherever you need it from there.

Cheers,
Askar

Hi Falko,

The current state is: The Freemarker scripting engine always returns a String. The engine makes a typed StringValue out of that and the String value serializer tries to squeeze it into the varchar field. What we need is an ObjectValue that contains the String. In that case, the Java object serializer will kick in and serialize the String as a blob. For non-typed-value APIs, this difference would not be noticeable. However, there is currently no dedicated extension point for conversion of script result variables.

As a workaround, you could do the following:

Subclass org.camunda.bpm.engine.impl.scripting.ScriptFactory such that it wraps Freemarker scripts in a custom implementation of org.camunda.bpm.engine.impl.scripting.ExecutableScript. That custom implementation could perform a conversion of String to ObjectValue in the evaluate method. Register the script factory in the process engine configuration.

Cheers,
Thorben

Thank you for your feedback. I solved my problem by not storing the result in a variable:

public class AsynchronousSoapServiceTask extends AbstractBpmnActivityBehavior {

  public static final String EXECUTION_ID = "executionId";
  
	public void execute(final ActivityExecution execution) throws Exception {
	  execution.setVariableLocal("waitingAsynchronousServiceTask", "true");

    // invoke SYRIUS
	  String url = (String) execution.getVariable("url");
    String messageTemplate = (String) execution.getVariable("messageTemplate");
	  
	  ExecutableScript script = ScriptUtil.getScriptFromResource("freemarker", messageTemplate, ScriptUtil.getScriptFactory());
	  String payload = (String) Context
	      .getProcessEngineConfiguration()
	      .getScriptingEnvironment()
	      .execute(script, execution);
	  
	  System.out.println(payload);
	  
	  SoapHttpConnector soap = Connectors.getConnector(SoapHttpConnector.ID);
	  
	  soap.createRequest()
  	  .url(url)
  	  .payload(payload)
  	  .execute();
	  
	}
			
	public void signal(ActivityExecution execution, String signalName, Object signalData) throws Exception {
    execution.removeVariable("waitingAsynchronousServiceTask");
	  
	  // leave the service task activity:
	  leave(execution);
	}

}
1 Like