Hybris 业务流程轮询

Hybris business process polling

我需要在我的自定义业务流程中创建一个必须每 10 分钟执行一次直到返回特定操作的操作,有什么方法可以自定义 hybris 订单业务流程中操作的轮询间隔吗?我知道您可以配置超时但不能配置轮询间隔:

<wait id='waitForOrderConfirmation' then='checkOrder' prependProcessCode='true'>
<event>confirm</event>
<timeout delay='PT12H' then='asmCancelOrder'/>

需要自定义实现来实现这一点,并且需要使用 BusinessProcessParameterModel。

以下是根据 Dealy 进行重试的步骤。

创建 RepeatableAction。

import de.hybris.platform.processengine.model.BusinessProcessModel;
import de.hybris.platform.processengine.model.BusinessProcessParameterModel;
import de.hybris.platform.servicelayer.model.ModelService;
import de.hybris.platform.warehousing.process.BusinessProcessException;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Optional;


public interface RepeatableAction<T extends BusinessProcessModel>
{
    int COUNTER_STARTER = 1;

    ModelService getModelService();

    Optional<Integer> extractThreshold(T process);

    String getParamName();

    default void increaseRetriesCounter(final T process)
    {
        final Collection<BusinessProcessParameterModel> contextParameters = process.getContextParameters();

        final Optional<BusinessProcessParameterModel> paramOptional = extractCounter(contextParameters);

        paramOptional.ifPresent(this::incrementParameter);

        if (!paramOptional.isPresent())
        {
            final Collection<BusinessProcessParameterModel> newContextParameters = new ArrayList<>(contextParameters);

            final BusinessProcessParameterModel counter = getModelService().create(BusinessProcessParameterModel.class);
            counter.setName(getParamName());
            counter.setValue(COUNTER_STARTER);
            counter.setProcess(process);

            newContextParameters.add(counter);

            process.setContextParameters(newContextParameters);
            getModelService().save(process);
        }
    }

    default Optional<BusinessProcessParameterModel> extractCounter(
            final Collection<BusinessProcessParameterModel> contextParameters)
    {
        //@formatter:off
        return contextParameters.stream().filter(p -> getParamName().equals(p.getName())).findFirst();
        //@formatter:on
    }

    default void incrementParameter(final BusinessProcessParameterModel parameter)
    {
        final Object value = parameter.getValue();
        if (value instanceof Integer)
        {
            parameter.setValue((Integer) value + 1);

            getModelService().save(parameter);
        }
        else
        {
            //@formatter:off
            final String message = MessageFormat.format("Wrong process parameter '{}' type. {} expected, {} actual.", getParamName(),
                    Integer.class.getSimpleName(), value.getClass().getSimpleName());
            //@formatter:on

            throw new BusinessProcessException(message);
        }
    }

    default boolean retriesCountThresholdExceeded(final T process)
    {
        //@formatter:off
        final Optional<Integer> counterOptional = extractCounter(process.getContextParameters())
                .map(BusinessProcessParameterModel::getValue).filter(Integer.class::isInstance).map(Integer.class::cast);
        //@formatter:on

        final Optional<Integer> thresholdOptional = extractThreshold(process);

        final boolean counterSet = counterOptional.isPresent();
        final boolean thresholdSet = thresholdOptional.isPresent();

        boolean thresholdExceeded = false;

        if (counterSet && thresholdSet)
        {
            final int counter = counterOptional.get();
            final int threshold = thresholdOptional.get();
            thresholdExceeded = counter > threshold;
        }

        return counterSet && thresholdSet && thresholdExceeded;
    }
}

然后转到自定义操作并实现此接口,并根据某些条件将自定义转换设为重试,类似这样。

public class CustomAction extends AbstractAction<OrderProcessModel>
        implements RepeatableAction<OrderProcessModel>
        {
        
        private static final int MAX_RETRIES = 3;//make it configurable it's your choice
        @Override
    public Transition prepare(OrderModel order, OrderProcessModel process)
    {
        if (!retriesCountThresholdExceeded(process))
        {
            if (custom condition)
            {
                return Transition.OK;
            }
            getModelService().refresh(order);
            increaseRetriesCounter(process);
            return Transition.RETRY;
        }
        return Transition.NOK;
    }
        
        }
        
        @Override
    public Optional<Integer> extractThreshold(OrderProcessModel process)
    {
        return Optional.of(MAX_RETRIES);
    }

然后在process.xml动作条目应该是这样的。

<action id="customAction" bean="customAction">
        <transition name="OK" to="nextStep"/>
        <transition name="RETRY" to="waitForOrderConfirmation"/>
        <transition name="NOK" to="cancelOrderAction"/>
    </action>

<wait id='waitForOrderConfirmation' then='checkOrder' prependProcessCode='true'>
<event>confirm</event>
<timeout delay='PT12H' then='asmCancelOrder'/>
<wait>

注意:请根据新 12 小时的要求设置 dealy 似乎太多了