REST ๋ฐ ์›Œํฌํ”Œ๋กœ์šฐ ์—”์ง„(Java ์—†์Œ) ๊ธฐ๋ฐ˜์˜ ์†์‰ฌ์šด ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜์„ ์œ„ํ•ด Camunda ์‚ฌ์šฉ

ํ—ค์ด ํ•˜๋ธŒ๋ฅด! ๋‚˜๋Š” ๊ธฐ์‚ฌ์˜ ๋ฒˆ์—ญ์„ ๋‹น์‹ ์˜ ๊ด€์‹ฌ์— ์ œ์‹œํ•ฉ๋‹ˆ๋‹ค "(Java๋ฅผ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๊ณ ) ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฌ์šด REST ๊ธฐ๋ฐ˜ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜ ๋ฐ ์›Œํฌํ”Œ๋กœ ์—”์ง„์œผ๋กœ Camunda๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”." ๋ฒ ๋ฅธํŠธ ๋คผ์ปค.

07.07.2020๋…„ XNUMX์›” XNUMX์ผ, ๋ฒˆ์—ญ ์กฐํ•ญ ๋ฒˆ๋“œ ๋Ÿฌ์ปค

REST ๋ฐ ์›Œํฌํ”Œ๋กœ์šฐ ์—”์ง„(Java ์—†์Œ) ๊ธฐ๋ฐ˜์˜ ์†์‰ฌ์šด ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜์„ ์œ„ํ•ด Camunda ์‚ฌ์šฉ

์ €๋Š” ์ข…์ข… Java๊ฐ€ ์•„๋‹Œ C# ๊ฐœ๋ฐœ์ž, Node.JS/JavaScript ๊ฐœ๋ฐœ์ž ๋˜๋Š” Golang ์• ํ˜ธ๊ฐ€์™€ ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ์•„ํ‚คํ…์ฒ˜์— ๋Œ€ํ•ด ๋…ผ์˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๋“ค ๋ชจ๋‘๋Š” ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค ์•„ํ‚คํ…์ฒ˜์˜ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด ํ•„์š”ํ•˜๊ฑฐ๋‚˜ ์›Œํฌํ”Œ๋กœ๋ฅผ ๊ฐ„์†Œํ™”ํ•˜๊ณ  ์ฃผ๋ฌธ, ์‹œ๊ฐ„ ์ดˆ๊ณผ ์ฒ˜๋ฆฌ, Saga ๋ฐ ๋ณด์ƒ ํŠธ๋žœ์žญ์…˜ ๊ธฐ๋Šฅ์„ ์–ป๊ธฐ ์œ„ํ•œ ๋„๊ตฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋Š” ์‚ฌ์‹ค์— ์ง๋ฉดํ•ด ์žˆ์Šต๋‹ˆ๋‹ค.

BPM ํ”Œ๋žซํผ Camunda์˜ ์˜คํ”ˆ ์†Œ์Šค ๊ทธ๋Ÿฌํ•œ ์ž‘์—…์— ์ข‹์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ž ์นœํ™”์„ฑ์€ ์ œํ’ˆ์˜ ์ฃผ์š” ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ํ•ด๋‹น ๋ฌธ์„œ๋ฅผ ์‚ดํŽด๋ณด๋ฉด Camunda์˜ "์นœ์ˆ™ํ•จ"์ด ์ฃผ๋กœ Java ๊ฐœ๋ฐœ์ž๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•œ๋‹ค๋Š” ์ธ์ƒ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ”Œ๋žซํผ์€ ์ž์‹ ์˜ ๊ธฐ๋Šฅ๊ณผ ํ™•์žฅ์„ ์—ฐ๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋งŽ์€ ์˜ต์…˜์„ ์ œ๊ณตํ•˜์ง€๋งŒ ๋ชจ๋‘ Java๋กœ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค. ์ง„์งœ์•ผ?

์•„๋‹ˆ์š”! ์‹ค์ œ๋กœ Java ์ง€์‹ ์—†์ด๋„ Camunda๋ฅผ ์‰ฝ๊ฒŒ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์›ํ•˜๋Š” ์–ธ์–ด๋กœ ์ฝ”๋“œ ์•„ํ‚คํ…์ฒ˜๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ธฐ์‚ฌ์—์„œ๋Š” ๋‹ค์Œ์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  • ๊ธฐ๋ณธ ์•„ํ‚คํ…์ฒ˜;
  • REST API
  • Java ์ด์™ธ์˜ ์–ธ์–ด์— ๋Œ€ํ•œ ๊ธฐ์กด ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋Œ€ํ•œ ์กฐ์–ธ
  • C# ๋ฐ Node.JS๋ฅผ ์‚ฌ์šฉํ•œ ์˜ˆ;
  • Camunda ์„œ๋ฒ„(Docker ๋˜๋Š” Tomcat)๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ๋ฐฉ๋ฒ•.

๊ตฌ์กฐ

Camunda๋Š” Java๋กœ ์ž‘์„ฑ๋˜์—ˆ์œผ๋ฉฐ ์‹คํ–‰ํ•˜๋ ค๋ฉด JVM(Java Virtual Machine)์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. Camunda๋Š” ์›ํ•˜๋Š” ์–ธ์–ด๋กœ ์ž‘์„ฑํ•˜๊ณ  Camunda์™€ ํ•จ๊ป˜ REST๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” REST API๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

REST ๋ฐ ์›Œํฌํ”Œ๋กœ์šฐ ์—”์ง„(Java ์—†์Œ) ๊ธฐ๋ฐ˜์˜ ์†์‰ฌ์šด ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜์„ ์œ„ํ•ด Camunda ์‚ฌ์šฉ

Camunda์˜ ์›Œํฌํ”Œ๋กœ์šฐ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ XML ํŒŒ์ผ์ธ BPMN์œผ๋กœ ์ •์˜๋ฉ๋‹ˆ๋‹ค. ์œผ๋กœ ๋ชจ๋ธ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์นด๋ฌธ๋‹ค ๋ชจ๋ธ๋Ÿฌ.

์‚ฌ์ „ ๋นŒ๋“œ๋œ Docker ์ด๋ฏธ์ง€๋ฅผ ํ†ตํ•ด Camunda ์‹คํ–‰

Camunda๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฐ€์žฅ ์‰ฌ์šด ๋ฐฉ๋ฒ•์€ Docker๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. Camunda๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ ์ด ๋ฌธ์„œ์˜ ๋’ท๋ถ€๋ถ„์—์„œ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

REST ๋ฐ ์›Œํฌํ”Œ๋กœ์šฐ ์—”์ง„(Java ์—†์Œ) ๊ธฐ๋ฐ˜์˜ ์†์‰ฌ์šด ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜์„ ์œ„ํ•ด Camunda ์‚ฌ์šฉ

์ด ๊ฒฝ์šฐ ๊ฐ„๋‹จํžˆ ๋‹ค์Œ์„ ์‹คํ–‰ํ•˜์‹ญ์‹œ์˜ค.

  docker run -d -p 8080:8080 camunda/camunda-bpm-platform:latest

Linux, JVM ๋˜๋Š” Tomcat์— ๋Œ€ํ•ด ๊ฑฑ์ •ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. Dockerfile ๋ฐ ๊ธฐ๋ณธ ๋ฌธ์„œ(์˜ˆ: ํ•„์ˆ˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ์ง€์นจ)๋Š” ๋‹ค์Œ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊นƒํ—ˆ๋ธŒ.

Camunda Enterprise Edition์„ ์‹คํ–‰ํ•˜๋ ค๋ฉด ์‰ฝ๊ฒŒ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ๋„์ปค ํŒŒ์ผ.

๊ทธ๋Ÿฌ๋‚˜ Docker๋กœ Camunda๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ํ•œ ๊ฐ€์ง€ ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰, ํ•ญ์ƒ ์ตœ์‹  ์ˆ˜์ • ์‚ฌํ•ญ์ด ํฌํ•จ๋˜์ง€ ์•Š๋Š” Tomcat ๋ฒ„์ „์ด ์ƒ์„ฑ๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด ์ด ์˜ˆ์ œ์— ํ‘œ์‹œ๋œ ๋Œ€๋กœ ์›ํ•˜๋Š” Tomcat ๋ฐฐํฌ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ณ ์œ ํ•œ Docker ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ์•„๋ž˜ ์„ค๋ช…๋œ ์†”๋ฃจ์…˜ ์ค‘ ํ•˜๋‚˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ”„๋กœ์„ธ์Šค ๋ชจ๋ธ ๋ฐฐํฌ

์„ธ ๊ฐ€์ง€ ์ž‘์—…์„ ์—ฐ์†์œผ๋กœ ํŠธ๋ฆฌ๊ฑฐํ•˜๊ณ  ๋‚˜์ค‘์— ์‹คํŒจํ•  ๊ฒฝ์šฐ ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋œ ์ž‘์—…์„ ์ ์ ˆํ•˜๊ฒŒ ๋ณด์ƒํ•˜๋ ค๋Š” ์ผ๋ฐ˜์ ์ธ ์—ฌํ–‰ ์˜ˆ์•ฝ์— Saga ํ…œํ”Œ๋ฆฟ์„ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. BPMN ํ˜•์‹์œผ๋กœ ํ‘œํ˜„ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

REST ๋ฐ ์›Œํฌํ”Œ๋กœ์šฐ ์—”์ง„(Java ์—†์Œ) ๊ธฐ๋ฐ˜์˜ ์†์‰ฌ์šด ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜์„ ์œ„ํ•ด Camunda ์‚ฌ์šฉ

์ด์ œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ”„๋กœ์„ธ์Šค ๋ชจ๋ธ ๋ฐฐํฌ๋ฅผ ์œ„ํ•œ REST API. ์ด๋ฅผ trip.bpmn์œผ๋กœ ์ €์žฅํ•˜๊ณ  Docker๋ฅผ ํ†ตํ•ด Camunda๋ฅผ ์‹คํ–‰ํ•˜์—ฌ localhost:8080์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  curl -w "n" 
-H "Accept: application/json" 
-F "deployment-name=trip" 
-F "enable-duplicate-filtering=true" 
-F "deploy-changed-only=true" 
-F "[email protected]" 
http://localhost:8080/engine-rest/deployment/creat

์ด์ œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ์ƒˆ ์›Œํฌํ”Œ๋กœ ์ธ์Šคํ„ด์Šค REST API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ณด๋ ค๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์›Œํฌํ”Œ๋กœ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

  curl 
-H "Content-Type: application/json" 
-X POST 
-d '{"variables":{"someData" : {"value" : "someValue", "type": "String"}},"businessKey" : "12345"}}' 
http://localhost:8080/engine-rest/<!-- -->process-definition/key/<!-- -->FlowingTripBookingSaga<!-- -->/start

๋‹ค์Œ ํฅ๋ฏธ๋กœ์šด ์งˆ๋ฌธ์€ Camunda๊ฐ€ ์ž๋™์ฐจ ์˜ˆ์•ฝ๊ณผ ๊ฐ™์€ ์ ˆ์ฐจ๋ฅผ ์–ด๋–ป๊ฒŒ ํ˜ธ์ถœํ•˜๋Š”๊ฐ€์ž…๋‹ˆ๋‹ค. Camunda๋Š” ๋‚ด์žฅ๋œ ์ผ๋ถ€ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฆ‰์‹œ ์„œ๋น„์Šค๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ(Push-Principle) ์ปค๋„ฅํ„ฐ, ์ž‘์—… ํ•ญ๋ชฉ์„ ์ผ์ข…์˜ ๊ธฐ๋ณธ ์ œ๊ณต ์ˆœ์„œ๋กœ ๋ฐฐ์น˜ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์ž‘์—…์ž๋Š” REST๋ฅผ ํ†ตํ•ด ์ž‘์—… ํ•ญ๋ชฉ์„ ๊ฐ€์ ธ์˜ค๊ณ , ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ณ , Camunda์—๊ฒŒ ์™„๋ฃŒํ•˜๋ผ๊ณ  ์ง€์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(ํ’€ ์›์น™).

REST ๋ฐ ์›Œํฌํ”Œ๋กœ์šฐ ์—”์ง„(Java ์—†์Œ) ๊ธฐ๋ฐ˜์˜ ์†์‰ฌ์šด ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜์„ ์œ„ํ•ด Camunda ์‚ฌ์šฉ

๋จผ์ € ์‹คํ–‰ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค ๊ฐ€์ ธ์˜ค๊ธฐ ๋ฐ ์ž ๊ธˆ (๋‹ค๋ฅธ ์ž‘์—…์ž๊ฐ€ ๋™์‹œ์— ์ž‘์—…์„ ๋ฐ›์•„ ์‹œ์Šคํ…œ์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค):

  curl 
-H "Content-Type: application/json" 
-X POST 
-d <!-- -->'{"workerId":"worker123","maxTasks":1,"usePriority":true,"topics":[{"topicName": "reserve-car"}, "lockDuration": 10000, "variables": ["someData"]}]}'<!-- --> 
http://localhost:8080/engine-rest/external-task/fetchAndLock

๊ทธ๋Ÿผ Camunda์—๊ฒŒ ๋งํ•ด์ค˜ ์ž‘์—…์ž๊ฐ€ ์ž‘์—…์„ ์™„๋ฃŒํ–ˆ์Šต๋‹ˆ๋‹ค. (์ฒซ ๋ฒˆ์งธ ์š”์ฒญ์—์„œ ๋ฐ›์€ ์™ธ๋ถ€ ์ž‘์—… ID๋ฅผ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.):

  curl 
-H "Content-Type: application/json" 
-X POST 
-d <!-- -->'{"workerId":"worker123", "variables": {}}'<!-- --> 
http://localhost:8080/engine-rest/<!-- -->external-task/EXTERNAL_TASK_ID/complete

๊ทธ๊ฒŒ ๋‹ค์ž…๋‹ˆ๋‹ค. ์•„์ง Java๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ฃ ? ์‹œ์ž‘ํ•˜๊ธฐ์— ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค!

ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

REST API๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์€ ๋ชจ๋“  ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์—์„œ ์‰ฝ์Šต๋‹ˆ๋‹ค. JavaScript์—์„œ๋Š” JQuery๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  C#์—์„œ๋Š” System.Net.Http ๋ฐ Newtonsoft.Json์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด ์ž‘์—…์„ ํŽธ๋ฆฌํ•˜๊ฒŒ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์‹œ๊ฐ„์ด ์ข€ ๊ฑธ๋ฆด ๊ฑฐ์˜ˆ์š”. ๋”ฐ๋ผ์„œ ์ผ๋ถ€ ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ๋ช‡ ๊ฐ€์ง€ ๊ธฐ์„ฑ ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ž๋ฐ” ์Šคํฌ๋ฆฝํŠธ : ๋งํฌ. Camunda์˜ ์ง€์›;
  • ์ž๋ฐ” : ๋งํฌ. Camunda์˜ ์ง€์›;
  • ์”จ#:๋งํฌ ะธ ๋งํฌ. ์ด ๋‘ ํ”„๋กœ์ ํŠธ๋Š” ๋ชจ๋‘ ์ค‘๊ฐ„ ์ƒํƒœ์— ์žˆ์œผ๋ฉฐ ์‚ฌ์‹ค์ƒ ํœด๋ฉด ์ƒํƒœ์ด์ง€๋งŒ ์ข‹์€ ์ถœ๋ฐœ์ ์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • PHP : ๋งํฌ - ๋„ˆ๋ฌด ์™„์ „ํ•˜์ง€๋„ ์•Š๊ณ  ์ตœ์‹  API ๋ณ€๊ฒฝ ์‚ฌํ•ญ๋„ ํฌํ•จํ•˜์ง€ ์•Š์ง€๋งŒ ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ์ ํŠธ๋ฅผ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

JavaScript ๋ฐ Java๋ฅผ ์ œ์™ธํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” Camunda ์ œํ’ˆ ์ž์ฒด์˜ ์ผ๋ถ€๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. Camunda์˜ REST API ๊ธฐ๋Šฅ์„ ๋ชจ๋‘ ์ง€์›ํ•  ๊ฒƒ์ด๋ผ๊ณ  ๊ธฐ๋Œ€ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ํŠน์ • ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ํ•ด์„œ ๊ทธ๊ฒƒ์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ํ•ญ์ƒ Camunda์˜ REST API๋ฅผ ํ™•์ธํ•˜์„ธ์š”. ์ฐธ์กฐ ํ”„๋กœ์ ํŠธ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‹œ์ž‘์ ๊ณผ ํ…œํ”Œ๋ฆฟ์œผ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

C# ์˜ˆ

์œ„์˜ ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฐ„๋‹จํžˆ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  var camunda = new CamundaEngineClient("http://localhost:8080/engine-rest/engine/default/", null, null);
  // Deploy the BPMN XML file from the resources
  camunda.RepositoryService.Deploy("trip-booking", new List<object> {
        FileParameter.FromManifestResource(Assembly.GetExecutingAssembly(), "FlowingTripBookingSaga.Models.FlowingTripBookingSaga.bpmn")
     });
  
  // Register workers
  registerWorker("reserve-car", externalTask => {
    // here you can do the real thing! Like a sysout :-)
    Console.WriteLine("Reserving car now...");
    camunda.ExternalTaskService.Complete(workerId, externalTask.Id);
  });
  registerWorker("cancel-car", externalTask => {
    Console.WriteLine("Cancelling car now...");
    camunda.ExternalTaskService.Complete(workerId, externalTask.Id);
  });
  registerWorker("book-hotel", externalTask => {
    Console.WriteLine("Reserving hotel now...");
    camunda.ExternalTaskService.Complete(workerId, externalTask.Id);
  });
  // Register more workers...
  
  StartPolling();
  
  string processInstanceId = camunda.BpmnWorkflowService.StartProcessInstance("FlowingTripBookingSaga", new Dictionary<string, object>()
    {
      {"someBookingData", "..." }
    });

์™„์ „ํžˆ ์ž‘๋™ํ•˜๋Š” ์†Œ์Šค ์ฝ”๋“œ๋Š” ์˜จ๋ผ์ธ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งํฌ. ๋˜ ๋‹ค๋ฅธ ์˜ˆ๋Š” ๋‹ค์Œ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งํฌ.

Node.js์˜ ์˜ˆ

  var Workers = require('camunda-worker-node');
  var workers = Workers('http://localhost:8080/engine-rest', {
    workerId: 'some-worker-id'
  });
  
  workers.registerWorker('reserve-car', [ 'someData' ], function(context, callback) {
    var someNewData = context.variables.someData + " - added something";
    callback(null, {
      variables: {
        someNewData: someNewData
      }
    });
  });
  
  workers.shutdown();

๋” ๋งŽ์€ ์ •๋ณด๋Š” ํ™ˆํŽ˜์ด์ง€์—์„œ ํ™•์ธํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค github.com

Camunda๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•

"Camunda ๋…๋ฆฝํ˜• WAR"์ด ํฌํ•จ๋œ ์‚ฌ์šฉ์ž ์ •์˜ Docker ์ด๋ฏธ์ง€

Camunda์˜ ์‚ฌ์ „ ๊ตฌ์ถ•๋œ Docker ์ด๋ฏธ์ง€ ๋Œ€์‹  Tomcat์„ ์ง์ ‘ ์ค€๋น„ํ•œ ๋‹ค์Œ(์˜ˆ: ๊ณต์‹ Docker Tomcat ์ด๋ฏธ์ง€ ๊ธฐ๋ฐ˜) Camunda๋ฅผ ์†Œ์œ„ WAR ํŒŒ์ผ ์ค‘ ํ•˜๋‚˜๋กœ ๋ณต์‚ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

REST ๋ฐ ์›Œํฌํ”Œ๋กœ์šฐ ์—”์ง„(Java ์—†์Œ) ๊ธฐ๋ฐ˜์˜ ์†์‰ฌ์šด ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜์„ ์œ„ํ•ด Camunda ์‚ฌ์šฉ

์ถ”๊ฐ€ ์š”๊ตฌ ์‚ฌํ•ญ์ด ๋งŽ๊ณ  Java ๋นŒ๋“œ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ Camunda Standalone War๋ฅผ ์„ค์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ์˜ˆ์‹œ์™€ ๊ฐ™์ด Maven ๋นŒ๋“œ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ „์Ÿ ์„ค์ •์ด ํฌํ•จ๋œ Maven ๋˜๋Š” ์กฐ๋ฆฝ ์˜ค๋ฒ„๋ ˆ์ด๋ฅผ ์‚ฌ์šฉํ•œ Maven.

Camunda Tomcat ๋ฐฐํฌ ์‹œ์ž‘

๋˜ ๋‹ค๋ฅธ ์˜ต์…˜์€ Camunda Tomcat ๋ฐฐํฌํŒ์„ ๋‹ค์šด๋กœ๋“œํ•˜์—ฌ ์••์ถ•์„ ํ’€๊ณ  ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด์„œ๋Š” ์ปดํ“จํ„ฐ์— JRE(Java Runtime Environment)๋งŒ ์„ค์น˜๋˜์–ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์‰ฝ๊ฒŒ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ์—ฌ๊ธฐ์—์„œ ๋‹ค์šด๋กœ๋“œํ•˜์„ธ์š”.

REST ๋ฐ ์›Œํฌํ”Œ๋กœ์šฐ ์—”์ง„(Java ์—†์Œ) ๊ธฐ๋ฐ˜์˜ ์†์‰ฌ์šด ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜์„ ์œ„ํ•ด Camunda ์‚ฌ์šฉ

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด Tomcat์„ ๊ตฌ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์„œ์— ์„ค๋ช…๋˜์–ด ์žˆ์Œ. Tomcat์ด ๋ณต์žกํ•ด ๋ณด์ผ ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ๋งค์šฐ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  Google์€ ๊ทธ ๊ณผ์ •์—์„œ ํ•„์š”ํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ๊ฒƒ์— ๋Œ€ํ•œ ๋‹ต์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

Tomcat์„ ์‚ฌ์šฉํ•˜์—ฌ Camunda ์‹คํ–‰

๋งˆ์ง€๋ง‰ ๋Œ€์•ˆ์€ Tomcat์„ ์ง์ ‘ ์„ค์ •ํ•˜๊ณ  Camunda๋ฅผ ์„ค์น˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์„ค์น˜ ์„ค๋ช…์— ๋”ฐ๋ผ. ์˜ˆ๋ฅผ ๋“ค์–ด, ์›ํ•˜๋Š” Tomcat ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ Windows ์„œ๋น„์Šค๋กœ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ๋Š” ์˜ต์…˜์ด ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค.

Camunda๋ฅผ ์ƒ์‚ฐ์— ํˆฌ์ž…

์ผ๋ฐ˜์ ์œผ๋กœ Camunda๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ๋ช‡ ๊ฐ€์ง€ ์ตœ์ข… ์„ค์ •์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. Camunda์—๋Š” ์ด์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์„ค๋ช…ํ•˜๋Š” ์ง€์นจ์ด ์žˆ์ง€๋งŒ ์ด ๊ธฐ์‚ฌ์—์„œ๋Š” ์ด์— ๋Œ€ํ•ด ๋‹ค๋ฃจ์ง€ ์•Š์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ํ•˜๋‚˜๋งŒ ๋“ค๊ฒ ์Šต๋‹ˆ๋‹ค. ๋ฐฐํฌํŒ์˜ REST API๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ธ์ฆ์„ ์œ„ํ•ด ๊ตฌ์„ฑ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์„ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ†ต๊ณ„

๋ณด์‹œ๋‹ค์‹œํ”ผ, ์‚ฌ์šฉํ•˜๋Š” ์–ธ์–ด์— ๊ด€๊ณ„์—†์ด Camunda๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ์‰ฝ์Šต๋‹ˆ๋‹ค. ์ค‘์š”ํ•œ ์ ์€ ๋ชจ๋“  ์ƒํ˜ธ ์ž‘์šฉ์ด REST API๋ฅผ ํ†ตํ•ด ์ˆ˜ํ–‰๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํŠนํžˆ Docker๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์„ค์น˜๋„ ๋งค์šฐ ์‰ฝ์Šต๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€