How to update zeebe:input propety in "bpmn:serviceTask,bpmn:extensionElements and zeebe:ioMapping"

Hi, I’m using rest connectors on web modeler, I encountered a scenario where I needed to update the value of the input property (specifically the source) under a serviceTask. I searched for some information, but It still doesn’t work. Does anyone know how to do it? thanks a lot

Here is part of my code:

import {getBusinessObject, is } from "bpmn-js/lib/util/ModelUtil";
// bpmnModeler after instantiation of 'bpmn-js/lib/Modeler' ; 
function createModdleElement(elementType, properties, parent) {
      const moddle = bpmnModeler.get("moddle");
      const element = moddle.create(elementType, properties);
      parent && (element.$parent = parent);
      return element;
 }
//
function getExtensionElementsList(businessObject, type?: string) {
      const extensionElements = businessObject?.get("extensionElements");
      if (!extensionElements) return [];
      const values = extensionElements.get("values");
      if (!values || !values.length) return [];

      if (type) return values.filter((value) => is(value, type));

      return values;
    }
    function getProperties(bo) {
      return getExtensionElementsList(bo);
    }
//
    function getRelevantBusinessObject(element) {
      const businessObject = getBusinessObject(element);
      if (is(element, "bpmn:Participant")) {
        return businessObject.get("processRef");
      }
      return businessObject;
    }
//
    function addExtensionProperty(element, property) {
      try {
        const modeling = bpmnModeler.get("modeling");
        const prefix = 'zeebe';

        const businessObject = getRelevantBusinessObject(element);

        //  extensionElements
        let extensionElements = businessObject.get("extensionElements");
        console.log('extensionElements', extensionElements);
        // debugger
        if (!extensionElements) {
          extensionElements = createModdleElement("bpmn:ExtensionElements", { values: [] }, businessObject);
          modeling.updateModdleProperties(element, businessObject, { extensionElements });
        }
        let IoMapping = extensionElements.get('values')[1];
        console.log('IoMapping', IoMapping);
        
        // extensionElements properties
        let properties = getProperties(businessObject);
        console.log('properties', properties);
        
        // debugger
        if (!properties) {
          properties = createModdleElement(`${prefix}:IoMapping`, { values: [] }, extensionElements);
          modeling.updateModdleProperties(element, extensionElements, {
            values: [...extensionElements.get("input"), properties]
          });
        }
        // 
        const newProperty = createModdleElement(`${prefix}:Input`,{source: "http://www.test.com",
        target: "url"}, IoMapping);
        // let Input = IoMapping.get('inputParameters');
        console.log('newProperty',newProperty, property);
        // debugger
        modeling.updateModdleProperties(element, newProperty,
        {
          source: "333",
          target: "url"
        }
      );
      } catch (e) {
        console.log(e);
      }
    }

here is xml

<bpmn:serviceTask id="Activity_0gbt5lc" name="nsrt" zeebe:modelerTemplate="io.camunda.connectors.HttpJson.v2" zeebe:modelerTemplateVersion="8" zeebe:modelerTemplateIcon="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTgiIGhlaWdodD0iMTgiIHZpZXdCb3g9IjAgMCAxOCAxOCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTE3LjAzMzUgOC45OTk5N0MxNy4wMzM1IDEzLjQ0NzUgMTMuNDI4MSAxNy4wNTI5IDguOTgwNjUgMTcuMDUyOUM0LjUzMzE2IDE3LjA1MjkgMC45Mjc3NjUgMTMuNDQ3NSAwLjkyNzc2NSA4Ljk5OTk3QzAuOTI3NzY1IDQuNTUyNDggNC41MzMxNiAwLjk0NzA4MyA4Ljk4MDY1IDAuOTQ3MDgzQzEzLjQyODEgMC45NDcwODMgMTcuMDMzNSA0LjU1MjQ4IDE3LjAzMzUgOC45OTk5N1oiIGZpbGw9IiM1MDU1NjIiLz4KPHBhdGggZD0iTTQuOTMxMjYgMTQuMTU3MUw2Ljc4MTA2IDMuNzE0NzFIMTAuMTM3NUMxMS4xOTE3IDMuNzE0NzEgMTEuOTgyNCAzLjk4MzIzIDEyLjUwOTUgNC41MjAyN0MxMy4wNDY1IDUuMDQ3MzYgMTMuMzE1IDUuNzMzNTggMTMuMzE1IDYuNTc4OTJDMTMuMzE1IDcuNDQ0MTQgMTMuMDcxNCA4LjE1NTIyIDEyLjU4NDEgOC43MTIxNUMxMi4xMDY3IDkuMjU5MTMgMTEuNDU1MyA5LjYzNzA1IDEwLjYyOTggOS44NDU5TDEyLjA2MTkgMTQuMTU3MUgxMC4zMzE1TDkuMDMzNjQgMTAuMDI0OUg3LjI0MzUxTDYuNTEyNTQgMTQuMTU3MUg0LjkzMTI2Wk03LjQ5NzExIDguNTkyODFIOS4yNDI0OEM5Ljk5ODMyIDguNTkyODEgMTAuNTkwMSA4LjQyMzc0IDExLjAxNzcgOC4wODU2MUMxMS40NTUzIDcuNzM3NTMgMTEuNjc0MSA3LjI2NTEzIDExLjY3NDEgNi42Njg0MkMxMS42NzQxIDYuMTkxMDYgMTEuNTI0OSA1LjgxODExIDExLjIyNjUgNS41NDk1OUMxMC45MjgyIDUuMjcxMTMgMTAuNDU1OCA1LjEzMTkgOS44MDkzNiA1LjEzMTlIOC4xMDg3NEw3LjQ5NzExIDguNTkyODFaIiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K">
      <bpmn:extensionElements>
        <zeebe:taskDefinition type="io.camunda:http-json:1" retries="3" />
        <zeebe:ioMapping>
          <zeebe:input source="noAuth" target="authentication.type" />
          <zeebe:input source="GET" target="method" />
          <zeebe:input source="http://a" target="url" />
          <zeebe:input source="=454545" target="headers" />
          <zeebe:input source="20" target="connectionTimeoutInSeconds" />
          <zeebe:input source="20" target="readTimeoutInSeconds" />
        </zeebe:ioMapping>
        <zeebe:taskHeaders>
          <zeebe:header key="retryBackoff" value="PT0S" />
        </zeebe:taskHeaders>
      </bpmn:extensionElements>
      <bpmn:incoming>Flow_1w039n1</bpmn:incoming>
      <bpmn:outgoing>Flow_0zil8z7</bpmn:outgoing>
    </bpmn:serviceTask>
1 Like

I found the update method, but how to batch update multiple attributes of input

const newProperty = createModdleElement(`zeebe:Input`, property, IoMapping);
        // let Input = IoMapping.get('inputParameters');
        console.log('newProperty',newProperty, property);
        // debugger
        modeling.updateModdleProperties(element, IoMapping, {
          inputParameters: [newProperty]
});

You’re absolutely on the right track:

  • Modeling#updateModdleProperties is the way to go
  • You need to account for chained updates (“ensure extension elements exist”)
  • The simple way to do this is to wrap your change into a multi-command handler, cf. this. I don’t suggest you to rely on that one but replicate the mechanism. Don’t build your work on implementation details :wink:

Hope this helps.


Further reference needed, checkout how we do this internally.