Giter VIP home page Giter VIP logo

Comments (7)

nitram509 avatar nitram509 commented on June 8, 2024 6

FYI: I'm working on this and have pushed first working version (main branch).

from lib-bpmn-engine.

cq-z avatar cq-z commented on June 8, 2024

Suggestion:
add ”dump“ and ” regain“ api 。So that compatible on the storage implementation
The storage implementation can be create tables (events 、tasks...) to save state and data like:https://github.com/antlinker/flow/blob/develop/schema/s_flow.go

from lib-bpmn-engine.

nitram509 avatar nitram509 commented on June 8, 2024

Hi @cq-z thank you for your suggestion.
I will try my best to make it somewhat compatible, but will not make it a 1:1 fit.
I rather think of optimizing for this lib but allowing an optional "adapter function", which could map the schemas.

@cq-z May I ask: what use case do you have in mind, for making this suggestion?

PS:
See also https://github.com/nitram509/lib-bpmn-engine/blob/feature/export_and_import_BPMN_state/pkg/bpmn_engine/engine_marshal.go
for my latest work in progress.

from lib-bpmn-engine.

cq-z avatar cq-z commented on June 8, 2024

example :
Marshal to model like https://gorm.io/docs/has_many.html, after that model to save。
model Select, after that model Unmarshal to BpmnEngineState

Marshal support [] byte or struct , or like https://github.com/jinzhu/copier implementation BpmnEngineState to model
Whether the scalability is better

from lib-bpmn-engine.

cq-z avatar cq-z commented on June 8, 2024

support grom like demo

package main

import (
	"fmt"
	"github.com/jinzhu/copier"
	"github.com/nitram509/lib-bpmn-engine/pkg/bpmn_engine"
	"github.com/stretchr/testify/assert"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"testing"
)

type serializedBpmnEngine struct {
	Id                   int64                  `gorm:"foreignKey:autoIncrement"`
	Version              int                    `json:"version"`
	Name                 string                 `json:"name"`
	MessageSubscriptions []*MessageSubscription `json:"MessageSubscriptions,omitempty" gorm:"foreignKey:BpmnId"  copier:"GetMessageSubscriptions"`
	Processes            []ProcessInfo          `json:"Processes,omitempty" gorm:"foreignKey:BpmnId" copier:"GetProcessInstances"`
}
type MessageSubscription struct {
	Id                 int64 `gorm:"foreignKey:autoIncrement"`
	BpmnId             int64
	ElementId          string `json:"ElementId"`
	ElementInstanceKey int64  `json:"ElementInstanceKey"`
	ProcessInstanceKey int64  `json:"ProcessInstanceKey"`
	Name               string `json:"Name"`
	State              string `json:"State"`
	CreatedAt          int64  `json:"CreatedAt"`
}
type ProcessInfo struct {
	Id            int64 `gorm:"foreignKey:autoIncrement"`
	BpmnId        int64
	BpmnProcessId string `json:"BpmnProcessId"` // The ID as defined in the BPMN file
	Version       int32  `json:"Version"`       // A version of the process, default=1, incremented, when another process with the same ID is loaded
	ProcessKey    int64  `json:"ProcessKey"`    // The engines key for this given process with version

	// TODO: make them private again?
	Definitions   string `json:"definitions"`   // parsed file content
	ChecksumBytes string `json:"checksumBytes"` // internal checksum to identify different versions
}

var bpmnByte = `
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:zeebe="http://camunda.org/schema/zeebe/1.0" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:modeler="http://camunda.org/schema/modeler/1.0" id="Definitions_1u3x2yl" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="5.0.0" modeler:executionPlatform="Camunda Cloud" modeler:executionPlatformVersion="1.0.0">
  <bpmn:process id="simple-user-task" name="simple-user-task" isExecutable="true">
    <bpmn:startEvent id="StartEvent_1">
      <bpmn:outgoing>Flow_0xt1d7q</bpmn:outgoing>
    </bpmn:startEvent>
    <bpmn:sequenceFlow id="Flow_0xt1d7q" sourceRef="StartEvent_1" targetRef="user-task" />
    <bpmn:endEvent id="Event_1j4mcqg">
      <bpmn:incoming>Flow_1vz4oo2</bpmn:incoming>
    </bpmn:endEvent>
    <bpmn:sequenceFlow id="Flow_1vz4oo2" sourceRef="user-task" targetRef="Event_1j4mcqg" />
    <bpmn:userTask id="user-task" name="user-task">
      <bpmn:extensionElements>
        <zeebe:assignmentDefinition assignee="assignee" candidateGroups="candicate-groups" />
        <zeebe:formDefinition formKey="form-key" />
      </bpmn:extensionElements>
      <bpmn:incoming>Flow_0xt1d7q</bpmn:incoming>
      <bpmn:outgoing>Flow_1vz4oo2</bpmn:outgoing>
    </bpmn:userTask>
  </bpmn:process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="simple-user-task">
      <bpmndi:BPMNEdge id="Flow_1vz4oo2_di" bpmnElement="Flow_1vz4oo2">
        <di:waypoint x="370" y="117" />
        <di:waypoint x="432" y="117" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Flow_0xt1d7q_di" bpmnElement="Flow_0xt1d7q">
        <di:waypoint x="215" y="117" />
        <di:waypoint x="270" y="117" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
        <dc:Bounds x="179" y="99" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Event_1j4mcqg_di" bpmnElement="Event_1j4mcqg">
        <dc:Bounds x="432" y="99" width="36" height="36" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="Activity_102w2rp_di" bpmnElement="user-task">
        <dc:Bounds x="270" y="77" width="100" height="80" />
        <bpmndi:BPMNLabel />
      </bpmndi:BPMNShape>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>
`

func TestGrom(t *testing.T) {

	db, err := gorm.Open(mysql.Open("root:123456@tcp(127.0.0.1:3306)/test"), &gorm.Config{})
	if err != nil {
		panic("failed to connect database")
	}

	db.AutoMigrate(serializedBpmnEngine{}, ProcessInfo{}, MessageSubscription{})

	// setup
	bpmnEngine := bpmn_engine.New("name")
	process, _ := bpmnEngine.LoadFromBytes([]byte(bpmnByte))

	variables := map[string]interface{}{
		"price": -50,
	}

	// when
	bpmnEngine.CreateAndRunInstance(process.ProcessKey, variables)
	processes := bpmnEngine.GetProcessInstances()
	var gormProcesses []ProcessInfo
	err = copier.Copy(&gormProcesses, processes)
	fmt.Println(err)
	messageSubscriptions := bpmnEngine.GetMessageSubscriptions()
	var gormMessageSubscriptions []*MessageSubscription
	err = copier.Copy(&gormMessageSubscriptions, messageSubscriptions)
	fmt.Println(err)
	s := &serializedBpmnEngine{
		Name:                 bpmnEngine.GetName(),
		Processes:            gormProcesses,
		MessageSubscriptions: gormMessageSubscriptions,
	}
	//err = copier.CopyWithOption(s, bpmnEngine, copier.Option{
	//	IgnoreEmpty: true,
	//	DeepCopy:    true,
	//	Converters: []copier.TypeConverter{
	//		{
	//			SrcType: []ProcessInfo{},
	//			DstType: []bpmn_engine.ProcessInfo{},
	//			Fn: func(src interface{}) (interface{}, error) {
	//				s, ok := src.(string)
	//				if !ok {
	//					return nil, fmt.Errorf("src type not matching")
	//				}
	//				return s, nil
	//			},
	//		},
	//	}})
	fmt.Println(err)
	// then
	db.Create(s)
	s1 := &serializedBpmnEngine{}
	db.Model(&serializedBpmnEngine{}).First(&s1)
	var bpmnEngine1 bpmn_engine.BpmnEngineState
	err = copier.CopyWithOption(&bpmnEngine1, s1, copier.Option{})
	assert.Equal(t, bpmnEngine1, bpmnEngine)
}

from lib-bpmn-engine.

cq-z avatar cq-z commented on June 8, 2024

Other solutions:
bpmnEngine to json, json to grom struct.
grom struct to json , json to bpmnEngine.

from lib-bpmn-engine.

eriknyk avatar eriknyk commented on June 8, 2024

@nitram509 any idea when feature/export_and_import_BPMN_state will be merged to main branch, and release new version?
In terms of generic way to persist the state looks enough.

Regards.

from lib-bpmn-engine.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.