Program Start

image0 The Program Start element is located in the Event & Gateway drawer of the process editor palette.

Element Details

The Program Start element allows you to start a process by a custom trigger. Therefore, it is perfect to integrate legacy-systems or any java-implementation you can think of being useful in starting workflow-cases.

Inscription

Name Tab

The Name Tab is included in the mask of all process elements and contains the name and a description of the element.

Start Tab

On this tab you define the Java class to be executed.

Start tab

Start tab

Java Class

Fully qualified name of the Java class that implements the IProcessStartEventBean interface. Use the New Bean Class Wizard image2 to create a new Java source file with an example implementation of the bean class.

Permission

Defines the role that is required to be able to start a process. The bean will set up an authorized session that calls the fireProcessStartEventRequest() from the eventRuntime to trigger a process.

Editor Tab

The custom editor UI provided by the implementation of IProcessStartEventBean to configure its execution.

Editor Tab

A custom editor example

Implementation

To initiate a custom bean implementation for your third party system, you start most conveniently by using the New Class image2 button on the Start Tab. The wizard will create a minimal sample implementation that works already. You can then adjust it to your needs.

API reference

The Program Start consumes a Java class that implements the IProcessStartEventBean interface. This implementation is responsible to initiate a new process by calling the method fireProcessStartEventRequest of IProcessStartEventBeanRuntime. The common way to implement a Start Event Bean is to extend from AbstractProcessStartEventBean.

If you use an Axon Ivy Cluster, you may mark your implementation with the IMultiNodeCapable interface. This will enable your Program Start not only on the master node, but on all available nodes.

Custom configuration

Very likely your Program Start implementation will accept configuration parameters to define the local environment. For instance a system specific file path to look for files being produced by a legacy system.

We help you with these configs by providing an accessor to statically configured element configuration via getConfiguration().

Custom editor

To define your custom configuration on the process inscription mask, you must supply an inner Editor class implementation. We recommend to extend your implementation from UiEditorExtension.

This editor class is responsible for two things: Firstly, to create UI widgets, which display configuration values. And secondly, to map configuration data onto these widgets:

1. The initUiFields method supports you in creating widgets for the editor. Currently labels, scriptEditors and textEditors are supported.

2. The ConfigurableExtensionEditor provides methods to read and write configurations, in order to bind them to previously created ui widgets.

Example implementation

 1package com.axonivy.wf.custom;
 2
 3import java.io.IOException;
 4import java.nio.file.Files;
 5import java.nio.file.Path;
 6import java.util.List;
 7import java.util.Map;
 8import java.util.Properties;
 9import java.util.concurrent.TimeUnit;
10import java.util.stream.Collectors;
11import java.util.stream.Stream;
12
13import ch.ivyteam.ivy.process.eventstart.AbstractProcessStartEventBean;
14import ch.ivyteam.ivy.process.extension.ui.ExtensionUiBuilder;
15import ch.ivyteam.ivy.process.extension.ui.IUiFieldEditor;
16import ch.ivyteam.ivy.process.extension.ui.UiEditorExtension;
17import ch.ivyteam.ivy.request.RequestException;
18import ch.ivyteam.util.PropertiesUtil;
19
20public class ErpInvoice extends AbstractProcessStartEventBean {
21
22  public ErpInvoice() {
23    super("ErpInvoice", "Integrates ERP updates driven by CSV files");
24  }
25
26  @Override
27  public void poll() {
28    Properties configs = PropertiesUtil.createProperties(getConfiguration());
29    int seconds = Integer.parseInt(configs.getProperty(Config.INTERVAL, "60"));
30    getEventBeanRuntime().setPollTimeInterval(TimeUnit.SECONDS.toMillis(seconds));
31
32    String path = configs.getProperty(Config.PATH, "");
33    try (Stream<Path> csv = Files.list(Path.of(path))) {
34      List<Path> updates = csv.collect(Collectors.toList());
35      startProcess("new stock items", Map.of("sheets", updates));
36    } catch (IOException ex) {
37      getEventBeanRuntime().getRuntimeLogLogger().error("Failed to check ERP for updates", ex);
38    }
39  }
40
41  private void startProcess(String firingReason, Map<String, Object> parameters) {
42    try {
43      getEventBeanRuntime().fireProcessStartEventRequest(null, firingReason, parameters);
44    } catch (RequestException ex) {
45      getEventBeanRuntime().getRuntimeLogLogger().error("Failed to init ERP driven process", ex);
46    }
47  }
48
49  public static class Editor extends UiEditorExtension {
50
51    private IUiFieldEditor path;
52    private IUiFieldEditor interval;
53
54    @Override
55    public void initUiFields(ExtensionUiBuilder ui) {
56      ui.label("Path to read .CSV stock-item changes:").create();
57      path = ui.textField().create();
58
59      ui.label("Interval in seconds to check for changes:").create();
60      interval = ui.scriptField().requireType(Integer.class).create();
61    }
62
63    @Override
64    protected void loadUiDataFromConfiguration() {
65      path.setText(getBeanConfigurationProperty(Config.PATH));
66      interval.setText(getBeanConfigurationProperty(Config.INTERVAL));
67    }
68
69    @Override
70    protected boolean saveUiDataToConfiguration() {
71      clearBeanConfiguration();
72      setBeanConfigurationProperty(Config.PATH, path.getText());
73      setBeanConfigurationProperty(Config.INTERVAL, interval.getText());
74      return true;
75    }
76  }
77
78  private interface Config {
79    String PATH = "path";
80    String INTERVAL = "interval";
81  }
82
83}