[開発][Python] 開発標準の話 ー 可読性て大切

Python にもちゃんと Javadoc なものがある。




ref.

[Python]可読性を上げるための、docstringの書き方を学ぶ(NumPyスタイル)
https://qiita.com/simonritchie/items/49e0813508cad4876b5a

tag : Python

2018-06-14 07:03 : 開発 : コメント : 0 : トラックバック : 0 :

[開発][DB][MySQL] データ更新で接続エラーになる

■ 事象
MySQL server has gone away
ER_NET_PACKET_TOO_LARGE

■ 原因
許容データ量オーバー

■ 確認
mysql> show variables like 'max_allowed_packet';

■ 詳細
The largest possible packet that can be transmitted to or from a MySQL 8.0 server or client is 1GB.

When a MySQL client or the mysqld server receives a packet bigger than max_allowed_packet bytes, it issues an ER_NET_PACKET_TOO_LARGE error and closes the connection. With some clients, you may also get a Lost connection to MySQL server during query error if the communication packet is too large.
shell> mysql --max_allowed_packet=32M
shell> mysqld --max_allowed_packet=128M

ref.
B.5.2.9 Packet Too Large
https://dev.mysql.com/doc/refman/8.0/en/packet-too-large.html

tag : max_allowed_packet DB MySQL ER_NET_PACKET_TOO_LARGE

2018-04-30 13:50 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] AWS の CLI を叩く

tag. AWS S2 CLI aws s3

ローカルマシンでAWS CLIを実行するには、以下の4つの情報が必要
- アクセスキー
- シークレットアクセスキー
- 接続先のAWSリージョン
- 出力フォーマット

-----------------------------------

バケットにオブジェクトを転送
aws s3 cp sample.txt s3://sample.bucket

ローカルからS3にコピー
aws s3 cp
S3からローカルにコピー
aws s3 cp
S3からS3にコピー
aws s3 cp
ディレクトリを再帰的にコピー
aws s3 cp bar/ s3://workbt/ --recursive
aws s3 cp bar s3://workbt/ --exclude "*" --include "*.txt" --recursive
aws s3 cp bar s3://workbt/ --exclude "*" --include "*.txt" --include "*.jpg" --recursive


ローカルからS3に移動
aws s3 mv test1.txt s3://workbt/hoge/
S3からローカルに移動
aws s3 mv s3://workbt/hoge/test1.txt ./
S3からS3に移動
aws s3 mv s3://workbt/hoge/test1.txt s3://workbt/fuga/


ファイルをローカルに落として開く
aws s3 cp s3://bucket_name/file.txt .
cat file.txt

ファイルをリモートから直接開く
aws s3 cp s3://bucket_name/file.txt -
aws s3 cp s3://bucket_name/file.txt - | less


バケットのオブジェクトを削除
aws s3 rm s3://sample.bucket/sample.txt

バケットのオブジェクト一覧を取得
aws s3 ls
aws s3 ls s3://sample.bucket

バケットのオブジェクト一覧を再帰的に取得
aws s3 ls workbt --recursive


色々ヘルプ
aws help
aws s3 help


ref.
AWS CLIのS3コマンドまとめ
http://www.task-notes.com/entry/20150904/1441335600
AWS CLIを使ってコマンドラインからAWSを操作する
http://tiro105.hateblo.jp/entry/2015/05/29/000809
aws s3コマンドでs3上のファイルをcatする裏技
https://chat-rate.com/it/3230/

tag : AWS S2 CLI aws s3

2018-03-16 23:56 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] 暗号に使用される塩 - SALT


tag. hash sha1 md5 salt encryption decryption SALT

user の password などは DB などに保存して置くのが一般的
password を平文で DBに保存して置くと、
DB に access できる保守運用者などに情報が筒抜け。
何かの拍子に情報が流出する恐れもある

なので、
DB に保存する password などの個人情報は、ハッシュ化してから DB に保存する
ハッシュ化された文字列だけでは、基本、複合化(復元)できない。
しかし、

ハッシュ化方法は md5sha1 など複数ある
ありがちな password は、すでに 平文とhash化された文字列の対応が解析されている。
プラス、レインボーテーブルといったテクニックで元の平文を復元される可能性もある。
そこで、SALT

元の平文に余計な文字列を付け足してからハッシュすることで、
よくあるハッシュ文字列になることを避けることでセキュリティを上げるというもの。
この余計な文字列を SALT という。


ref.
パソコンなどの「暗号」において 「塩」「ソル
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q12146344492

tag : hash sha1 md5 salt encryption decryption SALT

2018-02-16 22:07 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] LZO という Redshift の圧縮エンコード

tag.
LZO lzo Amazon Redshift type compression distkey sortkey constraint

Amazon Redshift でのテーブル定義の要素は 以下の5つ
その内、2 ~ 3 が Redshift 特有のもの。

1.データの型(data types)
2.列圧縮タイプ(column compression types)
3.分散キー(distkey)
4.ソートキー(sortkey)
5.制約(constraint)

LZO エンコードは、列圧縮タイプ の1つで、非常に高い圧縮率と良好なパフォーマンスを実現するんだそうだ

ref.
Amazon Redshift データ型と列圧縮タイプのまとめ(データ型&列圧縮タイプ対応表付)
https://dev.classmethod.jp/cloud/aws/amazon-redshift-data-types-and-column-compression-types/

tag : LZO lzo Amazon Redshift type compression distkey sortkey constraint

2018-02-13 20:40 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] Python 入門 - とりあえず意気込みだけ

Python入門編1:プログラミングを学ぶ
https://paiza.jp/works/python3/primer/beginner-python1

paiza.io
https://paiza.io/ja/projects/new

Python入門 サンプル集
https://algorithm.joho.info/programming/python/sample-code-py/

Python入門
https://www.pythonweb.jp/tutorial/

tag : Python paiza tutorial sample

2018-02-12 23:04 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] Luigi - データフロー制御フレームワーク -Pythonベース

Luigi Python dataflow flamework Spotify bigdat

Luigi
ルイージ
Pythonで書かれたデータフロー制御フレームワーク
Spotifyが開発
batch dat aprocessing in Python
データのクレンジングやフィルタ処理を容易にするもの
HadoopやTreasure Dataとも相性良い

リポジトリ
https://github.com/spotify/luigi

ref.
データフロー制御フレームワークLuigiを使ってビッグデータ解析をする
https://qiita.com/colspan/items/453aeec7f4f420b91241
Python: データパイプライン構築用フレームワーク Luigi を使ってみる
http://blog.amedama.jp/entry/2017/05/13/203907
Luigi によるワークフロー管理
https://qiita.com/k24d/items/fb9bed08423e6249d376
Luigiでデータ処理をきれいに書こう
https://www.rco.recruit.co.jp/career/engineer/blog/akiba-python-luigi-01/
Luigi で作成するワークフローの再利用性・メンテナンス性を高めるために
https://qiita.com/ngr_t/items/b928bc13457571e25519
Hello Worldタスクを作ってみた | Luigi Advent Calendar 2016 #01
https://dev.classmethod.jp/tool/advent_calendar_2016_luigi_12_1_helloworld/

tag : Luigi Python dataflow flamework Spotify bigdat

2018-01-04 09:04 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] PHP/Ruby用ローカル開発環境の構築 [Windows編] - Vagrant, VirtualBox

## VirtualBox - install
## Vagrant - install

## 流れ - サーバ設定/VM起動
Vagrantfileでserverの設定を読み込みVirtualBoxを立ち上げる

1 server - 1 folder
Windows
|-- MyVagrant
|    |-- MyCentOS
|    |    |-- Server1 >> setting @Vagrantfile - e.g. 192.168.33.10
|    |-- MyProject
|    |    |-- Server2 >> setting @Vagrantfile - e.g. 192.168.33.11
|

WindowsのPowerShellでコマンドを入力する
Windows + s >> PowerShell
vagrant plugin install vagrant-vbguest

mkdir MyVagrant
cd MyVagrant
mkdir MyCentOS
cd MyCentOS
vagrant init bento/centos-6.8

// Vagrantfile ----------
config.vm.network "private_network", ip: "192.168.33.10"
---------- Vagrantfile //
vagrant up
vagrant status
exit

## PuTTY - パティ
install

## VMへの接続
PuTTY
- IP : 192.168.33.10
- Connection Type : SSH
- Saved Sessions : MySentOS >> Save
>> Open

login as: vagrant
vagrant@192.168.33.10's password: vagrant
[vagrant@localhost ~]$

## VMの初期設定
# OSのアップデート
sudo yum -y update
# スクリプトを入手するためのgitのインストール
sudo yum -y install git
# gitでアプリケーション設定用のスクリプトのダウンロード
git clone https://github.com/dotinstallres/centos6.git
# centos6フォルダに移動
cd centos6
# スクリプトの実行
./run.sh
# もろもろの設定を反映
exec $SHELL -l

## ファイル転送ソフト
cyberduck >> install

## hosts - 特定IPに名前を付ける

ref.
ローカル開発環境の構築 [Windows編] (全14回)
http://dotinstall.com/lessons/basic_localdev_win_v2

tag : PHP Ruby Vagrant VirtualBox CentOS PowerShell cyberduck hosts

2018-01-04 08:42 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] Python で Hello World

Python

1991年に登場したプログラミング言語
- フリーソフト/オープンソース/simple/取得容易/オブジェクト指向/クロスプラットフォーム
- データ解析、機械学習にも用いられている
https://www.python.org
https://docs.python.org/3/
https://www.python.jp

$ python -v
Python 3.5.2
$ pwd
/home/vagrant/python_lessons
$ touch myapp.py
$ vi myapp.py

// myapp.py ----------
# 行末のセミコロンは省略可
print("Hello World")

'''
複数行のコメント方法:
シングル/ダブルクオーテーション3つで囲む
'''
---------- myapp.py //

$ python myapp.py
Hello World

// myapp.py ----------
# 変数 - 値の再代入可能
msg = "Hello World"
print(msg)
msg = "Hello Again"
print(msg)

# 定数 - 値の再代入不可
# 慣習的ルールで実際は再代入可能
ADMIN_EMAIL = "account@domain.com"

# 文字列
charLine = "he\nllo" + "wor\tld"
charLines = """


print(charLine)
print(charLines)

# 数値
i = 12
f = 34.5

# 論理値
flag = True # False

# データ演算
x = 10
pring(x / 3) # 3.33..
pring(x // 3) # 3..
pring(x % 3) # 1
pring(x ** 2) # 100

y = 4
y += 12
print(y) # 16

print(True and False) # False
print(True or False) # True
print(not True) # False

print("hello " * 3) # hello hello hello
---------- myapp.py //

ref.
Python 3入門 (全31回)
https://dotinstall.com/lessons/basic_python_v3

tag : Python

2018-01-04 08:05 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] Git環境の構築 - GitBashのインストール

Git Quick Reference
git --version
git config --global user.name "sample name"
git config --global user.email sample@example.com
git config --list
git init
git status
git add
git commit -m "first commit"
git log


■ 詳細
以下より「Git SCM to Windows」をDL
http://gitforwindows.org
全てデフォルトのままでインストール実行

Git Bash とは
Windowsのコマンドプロンプトでgit操作する為のツール(ターミナル)
Git for Windows」がインストールできていれば使用可能になる

■ Linuxな基礎操作
$ echo ~ ホームディレクトリの表示
$ ls 現在のディレクトリの表示
$ cd xxx/xxx xxx/xxxディレクトリへの移動
$ cd ../ 一つ上のディレクトリへ移動
$ mkdir ディレクトリの作成
$ mv hoge.txt foo/boo foo/booディレクトリにhoge.txtを移動する
$ cp hoge.txt newhoge.txt hoge.txtを複製しnewhoge.txtという名にする
$ touch new.txt new.txtというファイルを作成する
$ rm old.txt old.txtというファイルを削除する

Gitな基礎設定
コミットする際に使うユーザ名とメールアドレスの設定
$ git config --global user.name "sample name"
$ git config --global user.email sample@example.com
これでホームディレクトリに「.gitconfig」というファイルができる

SSHキーの作成
BitbucketやGitHubなどのリモートリポジトリを利用する場合は、安全に通信を行うためにSSHでの接続を行うのが良い
Git BashからSSHキーを発行し、各サービスと連携しておく
詳細割愛
ref.
https://www.granfairs.com/blog/staff/gitbash-ssh
https://www.granfairs.com/blog/staff/ssh-passphrase

Git Bashを見やすくする
割愛..


ref.
WindowsにGitをインストールする
https://www.granfairs.com/blog/cto/install-git-for-windows
WindowsでGitを始めたらまず確認!Git Bashの設定&ショートカット
https://www.granfairs.com/blog/staff/gitbash-setting-shortcut
初心者でもWindowsやMacでできる、Gitのインストールと基本的な使い方 (2/5)
http://www.atmarkit.co.jp/ait/articles/1603/31/news026_2.html

tag : Git GitBash

2017-12-27 09:00 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] Activitiとは

Activitiとは
- BPMエンジン(ワークフローエンジン)
- Activiti BPM Platform
- オープンソース(Apache License, Version 2.0) = 無償利用可能
- BPMN2.0ネイティブ対応
- Alfresco社がスポンサー

Activiti Modeler - Webベースのモデリングツール
Activiti Designer - Eclipseプラグインとして使用するモデリングツール
Activiti Explorer - ワークフローWebアプリケーション(ActivitiのWebフロントエンド)。簡単な申請画面等を作成できる。
★ 実際利用する場合は別途Webアプリケーションを作成し、ワークフロー・エンジンとしてactivitiを使用する


ref.
Activiti BPM Platformことはじめ(インストール方法とか)
http://labo-blog.aegif.jp/2013/06/activiti-bpm-platform.html

tag : Activiti BPM BPMN Modeler Designer Explorer

2017-11-30 15:16 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] 業務モデリング手法の話

[開発] 業務モデリング手法の話

tag. BPMN CMMN DMN OMG

BPM(Business Process Management)
BPMN(Business Process Modeling Notation)
業務モデリング手法

EA(Enterprise Architecture)
PDCA(Plan/Do/Check/Act)
SOA(Service Oriented Architecture)
BPMI(Business Process Management Initiative)
OMG(Object Management Group)
BAM(Business Activity Monitoring)
BI(BusinessInterigence)
SCM(Supply Chain Management)
BPO(Business Process Outsourcing)

ITアーキテクト Vol.6
https://ja.scribd.com/doc/153908716/ITアーキテクト-Vol-6-00-pdf#

BPMN 2.0の概要とビジネス・プロセス・モデリング
https://thinkit.co.jp/story/2010/09/10/1757

tag : BPMN CMMN DMN OMG

2017-11-30 15:14 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] ActivitUserGuide の気になるとこを掻い摘んでを訳しただけ

ActivitUserGuide の気になるとこを掻い摘んでを訳しただけ

■ 解決したら万々歳なネタ
- Activiti terminology の全容と各定義
   Model, >> 座標情報付きのプロセス定義の下書き
   Deployment, 作成したプロセス定義のファイナライズ、公開/出版に同義
   ProcessDefinition, 完成したプロセス定義、公開/出版したもの
   ProcessInstance, 各プロセス定義(型)を基に生成される各プロセス
   Task, プロセスを構成する要素
   Execution, プロセスの現状を示すポインタ
   Comment, 次タスクに回す際に添えるコメント。一回使い捨てなので更新不可なオブジェクト
   Attachment, 添付資料
   Entity, DBに登録する1レコード
   IdentityLink, タスクと担当者/グループのリンク情報
   Group, ユーザのグループ
   User, ユーザ
   Job ジョブ。タイマー/スケジューラの管理対象となるコンポーネント

- model と definition の違い
   >> 仮説: 前者が描画表記のドラフト版、後者がXML表記の最終形
   >> 正解。
   repository/models/37/source を照会すると座標情報がある
   対し、repository/process-definitions は座標情報を含まない
   process modelしてデプロイまで完了すると、座標情報が削除されプロセス定義となる

- event の実態
   >> 仮説: 各アクションのこと?

- Execution と プロセスインスタンスの違い
   >> 仮説: 前者は単なるポインタ、後者は普通のインスタンス

- v6 での Activiti Explorerの在り処
   >> 仮説: もはや無い!

- サブプロセスやサブタスク と 親プロセス/タスク の住み分け

- テナントの概念

========================================
3. Configuration

----------------------------------------
3.17. Event handlers

指定の出来事(Event)がActivitiエンジンで発生した時に知らせるActivitiの1メカニズム
利用方法
-configurationにて engine-wide なイベントリスナを追加するか、
-API (RuntimeService) 使ってruntimeで engine-wide なイベントリスナを追加する

イベントは、org.activiti.engine.delegate.event.ActivitiEvent のサブクラスであること
イベントの種別(event type)は後述参照

3.17.6. Supported event types

ref.
org.activiti.engine.delegate.event.ActivitiEventType

Engine
 - ENGINE_CREATED
 - ENGINE_CLOSED
Entity
 - ENTITY_CREATED
 - ENTITY_INITIALIZED
 - ENTITY_UPDATED
 - ENTITY_DELETED
 - ENTITY_SUSPENDED
 - ENTITY_ACTIVATED
Job/Timer
 - JOB_EXECUTION_SUCCESS
 - JOB_EXECUTION_FAILURE
 - JOB_RETRIES_DECREMENTED
 - TIMER_FIRED
 - JOB_CANCELED
Activitiy
 - ACTIVITY_STARTED
 - ACTIVITY_COMPLETED
 - ACTIVITY_CANCELLED
 - ACTIVITY_SIGNALED
 - ACTIVITY_MESSAGE_RECEIVED
 - ACTIVITY_ERROR_RECEIVED
 - ACTIVITY_COMPENSATE
Xxx
 - UNCAUGHT_BPMN_ERROR
Variable
 - VARIABLE_CREATED
 - VARIABLE_UPDATED
 - VARIABLE_DELETED
Task
 - TASK_ASSIGNED
 - TASK_CREATED
 - TASK_COMPLETED
Process
 - PROCESS_COMPLETED
 - PROCESS_CANCELLED
Membership
 - MEMBERSHIP_CREATED
 - MEMBERSHIP_DELETED
 - MEMBERSHIPS_DELETED

Entity とは、Attachment, Comment, Deployment, Execution, Group, IdentityLink, Job, Model, ProcessDefinition, ProcessInstance, Task, User のこと
Comment の更新はない
suspend/activateは、ProcessDefinitions, ProcessInstances/Execution, Tasks に対してある
XXX activiti-rest 見るにJobsに対してあるような..

========================================

8. BPMN 2.0 Constructs

----------------------------------------
8.2. Events

イベントとはプロセスのライフタイムで生じる何かをモデルするもの
常に丸で表記される
BPMN2.0に於いては2種類のイベントがある

キャッチイベント
 プロセス実行(process execution)がイベントに到達すると、triggerの発生を待つ
 triggerの種別は定義にて宣言

スローイベント
 プロセス実行(process execution)がイベントに到達すると、triggerが着火される

8.2.1. Event Definitions

8.2.2. Timer Event Definitions

8.2.3. Error Event Definitions

8.2.4. Signal Event Definitions

8.2.5. Message Event Definitions

XXX モデル:「プロセス定義」をモデルする的な動詞として使われている??
XXX XMLの情報をプロセス定義、描画された情報をモデルと言っている? >> 全ての辻褄が合う
XXX Activitiの内部実装的にどう分けているのかがちょっと疑問。
XXX 定義途中のものがモデルでfinalizeするとプロセス定義になる的な?

----------------------------------------
8.5. Tasks

8.5.1. User Task

A user task is used to model work that needs to be done by a human actor.
When the process execution arrives at such a user task, a new task is created in the task list of the user(s) or group(s) assigned to that task.

期限
Each task has a field, indicating the due date of that task.

担当者 (User assignment = assignee)
Only one user can be assigned as human performer to the task.
In Activiti terminology, this user is called the assignee. Tasks that have an assignee are not visible in the task lists of other people and can be found in the so-called personal task list of the assignee instead.

特定ユーザに紐づくタスクの一覧 (personal task list)
|List tasks = taskService.createTaskQuery().taskAssignee("kermit").list();

candidate task listでも照会可能
|List tasks = taskService.createTaskQuery().taskCandidateUser("kermit");
ただし、その場合はpotentialOwnerが予め設定されていること (humanPerformer constructで宣言)
この場合は、グループ指定も可能 - 定義時にユーザなのかグループなのか明記すること(Activitiのデフォルトはグループ)
所属グループが担当候補の場合も表記照会で参照できる

Activiti extensions for task assignment
担当者要素

候補担当者要素

候補グループ要素


Custom Assignment via task listeners
イベント生成時にタスクリスナを仕掛けて担当者を割り当てることも可能

8.5.2. Script Task
スクリプトで動的に実行されるタスク

8.5.3. Java Service Task

8.5.4. Web Service Task

8.5.5. Business Rule Task

8.5.6. Email Task

8.5.7. Mule Task

8.5.8. Camel Task

8.5.9. Manual Task

8.5.10. Java Receive Task

8.5.11. Shell Task

8.5.12. Execution listener

8.5.13. Task listener

========================================

11. History

HistoricProcessInstances
HistoricVariableInstances
HistoricActivityInstances
HistoricTaskInstances
HistoricDetails

tag : Activiti BPM BPMN Task Model Process Execution

2017-11-30 15:09 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] The Activiti API - ActivitUserGuide Chap.4 を訳しただけ

[開発] The Activiti API - ActivitUserGuide Chap.4 を訳しただけ

----------------------------------------
4.1. The Process Engine API and services

Acitivitiを使用する場合、Engine APIを使用するのが最も一般的
その核となる始点が ProcessEngine
ProcessEngine の構築方法は複数あり > https://www.activiti.org/userguide/index.html#configuration

ProcessEngine を経由して様々がサービスを取得できる - workflow, BPM など
ProcessEngine と 紐づくサービスはいずれもスレッドセーフ

img: https://www.activiti.org/userguide/images/api.services.png
activiti.cfg.xml --> ProcessEngineConfiguration --> ProcessEngine
ProcessEngine --> RepositoryService, RuntimeService, TaskService, ManagementService, IdentityService, HistoryService, FormService

中略

サービスはすべてステートレスなので、クラスタ環境でも容易にActiviti実行可能
サービス間の依存性もなし

RepositoryService
Activitiエンジンを使用する上で最初に必要なるサービス
デプロイとプロセス定義を管理および操作するための操作を提供するもの
言うまでもなく、プロセス定義はBPMN 2.0対応のもの
デプロイ単位はActivitiエンジンを内包するパッケージ単位
1つのデプロイで複数のBPMN 2.0 XMLファイルと他のリソースを保持可能。開発者次第。

# デプロイとは、それらデプロイパッケージ(deployment)をエンジンにアップロードするということ
# デプロイで全ての情報はパースされデータベースに永続化される
# デプロイされて初めてシステムに公開したこととなり、プロセスの開始が可能となる

RepositoryService の仕事
- デプロイパッケージ(deployment)やプロセス定義の照会
- デプロイパッケージの一時停止・再開 (デプロイパッケージ全体に対してか各プロセス定義に対して)
  一時停止により再開するまで当該プロセスに対するいかなる操作も不能になる
- エンジンによって自動生成さえる、デプロイパッケージ(deployment)やプロセス図の関連リソースのリトリーブ
- XMLでなくJavaでのプロセス定義POJOのリトリーブ

RuntimeService
RepositoryService が基本的に更新のない静的情報を扱うのに対し、RuntimeService は逆に動的なものを扱う。
RuntimeService は、プロセス定義から新規にプロセスインスタンスを生成/開始させる。
# プロセス定義は、プロセスの各ステップの構造や挙動を定義したもの
# プロセスインスタンスは、プロセス定義の各実行(execution)
# プロセス定義の各プロセスインスタンスは同時に実行可能なもの

RuntimeService は、プロセス変数(process variables)のリトリーブや保管も担う
# プロセス変数(process variables)は、プロセスインスタンスに割り振れるもので、
# そのプロセスの様々なコンストラクタから参照・利用できる
# e.g. an exclusive gateway often uses process variables to determine which path is chosen to continue the process

プロセスインスタンスや実行(execution)の参照もRuntimeServiceで可能となる
# Executions are a representation of the 'token' concept of BPMN 2.0. Basically an execution is a pointer pointing to where the process instance currently is.

RuntimeService は、プロセスインスタンスが処理続行に必要な外部のトリガーを待機している際も使用される
# プロセスインスタンスは様々な待機状態(wait states)を持てる。- this service contains various operations to signal the instance that the external trigger is received and the process instance can be continued.

■ TaskService
タスクは、実際のユーザのアクションを必要とするもので、ActivitiなどのBPMエンジンにおける核である
以下のようなタスク周辺のものは全てTaskServiceに分類される。

― ユーザ/グループに割り振られたタスクの照会
― プロセスインスタンスに依存しないスタンドアローンなタスクの生成
― 当該タスクがどのユーザに割り振られてるのか、どのユーザが関与するのかを管理
― タスクのクレイム(タスクの横取り, claim)や完了
# Claiming means that someone decided to be the assignee for the task, meaning that this user will complete the task.
# Completing means doing the work of the tasks. Typically this is filling in a form of sorts.

■ IdentityService
ユーザやグループを作成、更新、削除、照会するサービス
Activiti は、runtimeで一切ユーザ検証をしていない。
=タスクは誰にも割り当てられるし、その割り当てられた担当者がシステムに入れるアカウントであるかの検証などしないということ
=Active Directoryなど他のサービスとLDAPで繋いてActivitiを使用することも可能

■ FormService
FormService は、任意のサービスで、Activiti は、FormService が無くても問題なく作動する。
開始フォーム(start form)とタスクフォーム(task form)がある
開始フォーム - プロセスインスタンスが開始される前にユーザに表示されるフォーム
タスクフォーム - タスクを完了させる際にユーザに表示されるフォーム (憶測込み、原文: a task form is the form that is displayed when a user wants to complete a form.)
フォームを使用する場合はBPMN2.0プロセス定義内にフォームを定義する。

■ HistoryService
Activitiエンジンが取集した履歴データを照会するサービス
プロセスインスタンスの開始時刻や、各タスクの実行者や所要時間

■ ManagementService
Activitiを使用して独自のアプリを実装する分には必要の無いサービス
ManagementService は、以下を担う
- DBのテーブルや、テーブルのメタデータのリトリーブ
- Jobの照会や管理操作
# Jobs are used in Activiti for various things such as timers, asynchronous continuations, delayed suspension/activation, etc.

■ DynamicBpmnService
再デプロイ無しにプロセス定義を部分的に変更できるサービス
任意のタスクの担当者を変えたり、サービスタスクのクラス名を変えたり等


----------------------------------------
4.2. Exception strategy

非検査例外 org.activiti.engine.ActivitiException が基底例外
プロセス実行やAPI実行で発生する ActivitiException を除くと以下のようなサブクラスを持つ
ActivitiWrongDbException
ActivitiOptimisticLockingException
ActivitiClassLoadingException
ActivitiObjectNotFoundException
ActivitiIllegalArgumentException
ActivitiTaskAlreadyClaimedException


----------------------------------------
4.3. Working with the Activiti services

すぐに動確したいのなら
Activiti unit test template の org.activiti.MyUnitTest に testUserguideCode を追加して動かせば良い

4.3.1. Deploying the process

src/test/resources/org/activiti/test に VacationRequest.bpmn20.xml を作成し
RepositoryService 使って静的情報をデプロイする
# bpmn20.xml のコードは、https://www.activiti.org/userguide/index.html 参照

|ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine;
RepositoryService repositoryService = processEngine.getRepositoryService;
|repositoryService.createDeployment
| .addClasspathResource("org/activiti/test/VacationRequest.bpmn20.xml")
| .deploy;

|Log.info("Number of process definitions: " + |repositoryService.createProcessDefinitionQuery.count);

4.3.2. Starting a process instance

プロセス定義をActivitiエンジンにデプロイしたら、新規にプロセスインスタンスを開始できる
プロセス定義はいわゆるブループリント

実行状態にあるものは全て RuntimeService で参照可能
プロセスインスタンスは、プロセス定義にあるkeyを指定して開始できる

We’re also providing some process variables at process instance start, because the description of the first user task will use these in its expressions. Process variables are commonly used because they give meaning to the process instances for a certain process definition. Typically, the process variables are what make process instances differ from one another.

|Map variables = new HashMap;
|variables.put("employeeName", "Kermit");
|variables.put("numberOfDays", new Integer(4));
|variables.put("vacationMotivation", "I'm really tired!");

|RuntimeService runtimeService = processEngine.getRuntimeService;
|ProcessInstance processInstance = |runtimeService.startProcessInstanceByKey("vacationRequest", variables);

|// Verify that we started a new process instance
|Log.info("Number of process instances: " + |runtimeService.createProcessInstanceQuery.count);

4.3.3. Completing tasks

プロセスインスタンスが開始されたら、最初のユーザタスクに進む

タスク情報を取得して
|// Fetch all tasks for the management group
|TaskService taskService = processEngine.getTaskService;
|List tasks = |taskService.createTaskQuery.taskCandidateGroup("management").list;
|for (Task task : tasks) {
| Log.info("Task available: " + task.getName);
|}

タスクを完了させる
|ask task = tasks.get(0);

|Map taskVariables = new HashMap;
|taskVariables.put("vacationApproved", "false");
|taskVariables.put("managerMotivation", "We have a tight deadline!");
|taskService.complete(task.getId, taskVariables);

4.3.4. Suspending and activating a process

RepositoryService でプロセス定義をサスペンドできる。
サスペンドされている間は新しいプロセスインスタンスの生成はできない

|repositoryService.suspendProcessDefinitionByKey("vacationRequest");
|try {
| runtimeService.startProcessInstanceByKey("vacationRequest");
|} catch (ActivitiException e) {
| e.printStackTrace;
|}

4.3.5. Further reading

Javadoc をご参照あれ

----------------------------------------
4.4. Query API

エンジンからデータを取得して照会する方法は2つ
Query API を使用するか、native queries を使用する

Query API は、型セーフ。任意の条件を渡して使用する
自由自在にSQLを組みたければnative queriesを使用するまで

----------------------------------------
4.5. Variables

プロセスインスタンスが各ステップを実行するのに使用するもので、
Activiti においては variables と呼ばれ、データベースに保存される
# Variables can be used in expressions (for example to select the correct outgoing sequence flow in an exclusive gateway), in java service tasks when calling external services (for example to provide the input or store the result of the service call), etc.

プロセスインスタンスのみならず、
実行(executions)、ユーザタスクも variables を持てる
各 variable は、ACT_RU_VARIABLE テーブルに一行で格納される
# executions are specific pointers to where the process is active.

|ProcessInstance startProcessInstanceByKey(String processDefinitionKey, Map variables);

プロセス実行中で variables を追加できる
|void setVariable(String executionId, String variableName, Object value);
|void setVariables(String executionId, Map variables);

ローカルに設定することも可能。
これらは、その実行(execution)でしか参照できない。プロセスインスタンスまで伝搬させたくない情報に有用
# プロセスインスタンスは、実行(executions)をツリー構造で保持する
|void setVariableLocal(String executionId, String variableName, Object value);
|void setVariablesLocal(String executionId, Map variables);

valiables はfetchも可能
# TaskServiceに類似メソッドあることに留意あれ
つまり、実行(executions)などのタスクが、そのタスクでのみ有効なローカルvariablesを持てるということ
現在の実行(execution)ないしタスクのオブジェクトに対してvariablesを設定/リトリーブする

|execution.getVariables;
|execution.getVariables(Collection variableNames);
|execution.getVariable(String variableName);

|execution.setVariables(Map variables);
|execution.setVariable(String variableName, Object value);

Activiti v5.17以降であれば、varibalesの設定/照会のDBアクセスをより制御するすることも可能
|Map getVariables(Collection variableNames, boolean |fetchAllVariables);
|Object getVariable(String variableName, boolean fetchAllVariables);
|void setVariable(String variableName, Object value, boolean fetchAllVariables);

----------------------------------------
4.6. Transient variables

variable の一種でで、さも定番variableのようなもの
ただし、永続化されている訳ではない
特殊ユースケースで有用になる >> ご本家参照

----------------------------------------
4.7. Expressions

Activiti の形式変換は UELを使用している。
# UEL = Unified Expression Language, EE6に組み込まれた仕様

----------------------------------------
4.8. Unit testing

----------------------------------------
4.9. Debugging unit tests

----------------------------------------
4.10. The process engine in a web application

ProcessEngineはスレッドセーフ
マルチスレッドのWebアプリでの使用も可能

----------------------------------------

■ RepositoryService
 -createDeployment
 -deleteDeployment
 -setDeploymentCategory
 -setDeploymentKey
 -getDeploymentResourceNames
 -getResourceAsStream
 -changeDeploymentTenantId
 -createProcessDefinitionQuery
 -createNativeProcessDefinitionQuery
 -createDeploymentQuery
 -createNativeDeploymentQuery
 -suspendProcessDefinitionById
 -suspendProcessDefinitionByKey
 -activateProcessDefinitionById
 -activateProcessDefinitionByKey
 -setProcessDefinitionCategory
 -getProcessModel
 -getProcessDiagram
 -getProcessDefinition
 -isActiviti5ProcessDefinition
 -isProcessDefinitionSuspended
 -getBpmnModel
 -getProcessDiagramLayout
 -newModel
 -saveModel
 -deleteModel
 -addModelEditorSource
 -addModelEditorSourceExtra
 -createModelQuery
 -createNativeModelQuery
 -getModel
 -getModelEditorSource
 -getModelEditorSourceExtra
 -addCandidateStarterUser
 -addCandidateStarterGroup
 -deleteCandidateStarterUser
 -deleteCandidateStarterGroup
 -getIdentityLinksForProcessDefinition
 -validateProcess

■ RuntimeService
ProcessInstance
 -createProcessInstanceBuilder
 -startProcessInstanceByKey
 -startProcessInstanceByKeyAndTenantId
 -startProcessInstanceById
 -startProcessInstanceByMessage
 -startProcessInstanceByMessageAndTenantId
 -deleteProcessInstance
XXX
 -getActiveActivityIds
 -trigger
 -updateBusinessKey
User/Group
 -addUserIdentityLink
 -addGroupIdentityLink
 -addParticipantUser
 -addParticipantGroup
 -deleteParticipantUser
 -deleteParticipantGroup
 -deleteUserIdentityLink
 -deleteGroupIdentityLink
 -getIdentityLinksForProcessInstance
Variables
 -getVariables
 -getVariableInstances
 -getVariableInstancesByExecutionIds
 -getVariablesLocal
 -getVariableInstancesLocal
 -getVariable
 -getVariableInstance
 -hasVariable
 -getVariableLocal
 -getVariableInstanceLocal
 -hasVariableLocal
 -setVariable
 -setVariableLocal
 -setVariables
 -setVariablesLocal
 -removeVariable
 -removeVariableLocal
 -removeVariables
 -removeVariablesLocal
その他
 -getDataObjects
 -getDataObjectsLocal
 -getDataObject
 -getDataObjectLocal
 -createExecutionQuery
 -createNativeExecutionQuery
 -createProcessInstanceQuery
 -createNativeProcessInstanceQuery
 -suspendProcessInstanceById
 -activateProcessInstanceById
Event
 -signalEventReceived
 -signalEventReceivedWithTenantId
 -signalEventReceivedAsync
 -signalEventReceivedAsyncWithTenantId
 -messageEventReceived
 -messageEventReceivedAsync
 -addEventListener
 -removeEventListener
 -dispatchEvent
 -setProcessInstanceName
 -getEnabledActivitiesFromAdhocSubProcess
 -executeActivityInAdhocSubProcess
 -completeAdhocSubProcess
 -getProcessInstanceEvents

■ TaskService
基本操作
 -newTask
 -saveTask
 -deleteTask(s)
 -claim
 -unclaim
 -complete
 -delegateTask
 -resolveTask
 -setPriority
 -setDueDate
User/Group
 -setAssignee
 -setOwner
 -getIdentityLinksForTask
 -addCandidateUser
 -addCandidateGroup
 -addUserIdentityLink
 -addGroupIdentityLink
 -deleteCandidateUser
 -deleteCandidateGroup
 -deleteUserIdentityLink
 -deleteGroupIdentityLink
Query
 -createTaskQuery
 -createNativeTaskQuery
Variable
 -set/get/has/removeVariable(s)
 -set/get/has/removeVariable(s)Local
 -getVariableInstance(s)
 -getVariableInstanceLocal
 -getVariableInstancesLocalByTaskIds
 -getVariableInstancesLocal
その他
 -getDataObject(s)
 -addComment
 -getComment
 -deleteComment(s)
 -getTaskComments
 -getCommentsByType
 -getTaskEvents
 -getEvent
 -getProcessInstanceComments
 -createAttachment
 -saveAttachment
 -getAttachment
 -getAttachmentContent
 -getTaskAttachments
 -getProcessInstanceAttachments
 -deleteAttachment
 -getSubTasks

■ IdentityService
User
 -newUser(String)
 -saveUser(User)
 -createUserQuery()
 -createNativeUserQuery()
 -deleteUser(String)
 -checkPassword(String, String)
 -setAuthenticatedUserId(String)
 -setUserPicture(String, Picture)
 -getUserPicture(String)
 -setUserInfo(String, String, String)
 -getUserInfo(String, String)
 -getUserInfoKeys(String)
 -deleteUserInfo(String, String)
Group
 -newGroup(String)
 -createGroupQuery()
 -createNativeGroupQuery()
 -saveGroup(Group)
 -deleteGroup(String)
Membership
 -createMembership(String, String)
 -deleteMembership(String, String)

■ FormService
基本操作
 -saveFormData(String, Map)
StartForm
 -submitStartFormData
 -getStartFormKey
 -getStartFormData
 -getRenderedStartForm
TaskForm
 -submitTaskFormData
 -getTaskFormKey
 -getTaskFormData
 -getRenderedTaskForm

■ HistoryService
ProcessInstance
 -createHistoricProcessInstanceQuery
 -createNativeHistoricProcessInstanceQuery
 -deleteHistoricProcessInstance(String)
 -getHistoricIdentityLinksForProcessInstance(String)
 -createProcessInstanceHistoryLogQuery(String)
ActivityInstance
 -createHistoricActivityInstanceQuery
 -createNativeHistoricActivityInstanceQuery
TaskInstance
 -createHistoricTaskInstanceQuery
 -createNativeHistoricTaskInstanceQuery
 -deleteHistoricTaskInstance(String)
 -getHistoricIdentityLinksForTask(String)
Detail
 -createHistoricDetailQuery
 -createNativeHistoricDetailQuery
VariableInstance
 -createHistoricVariableInstanceQuery
 -createNativeHistoricVariableInstanceQuery

■ ManagementService
 -getTableCount/Name/MetaData
 -createTablePageQuery
 -createJobQuery
 -createTimerJobQuery
 -createSuspendedJobQuery
 -createDeadLetterJobQuery
 -executeJob
 -moveXxxJob
 -deleteJob
 -deleteTimerJob
 -setJobRetries, etc.

■ DynamicBpmnService
get/saveProcessDefinitionInfo
changeServiceTaskClassName
changeServiceTaskExpression
changeUserTaskName
changeUserTaskDueDate
changeUserTaskPriority
etc.


tag : Activiti BPMN BPM ProcessEngine RepositoryService RuntimeService

2017-11-18 16:59 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] activiti-webapp-rest2 を呼ぶCliant実装例

/**
*
*/
package tmp;


import java.net.URI;
import java.net.URISyntaxException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;

import org.activiti.engine.impl.util.json.JSONArray;
import org.activiti.engine.impl.util.json.JSONObject;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import com.google.gson.Gson;

/**
*
*/
@SuppressWarnings("rawtypes")
public class TmpRestTestMain {

private static final String URL_ROOT = "http://localhost:8081/activiti-webapp-rest2/service";
private static final String URL_ID_USERS = "/identity/users";
private static final String URL_RE_PROCESS_DEFINITIONS = "/repository/process-definitions";
private static final String URL_RU_PROCESS_INSTANCES = "/runtime/process-instances";
private static final String URL_RU_TASKS = "/runtime/tasks";
private static final String URL_HI_PROCESS_INSTANCES = "/history/historic-process-instances";

private static final String SIGN_METHOD_START = "\n■■ ";
private static final String SIGN_MARKABLE_STATUS = ">> ";

private RestTemplate restTemplate = new RestTemplate();//can be injected
private String userId = "kermit";//for Basic Auth, not in use yet.
private String userPw = "Kermit";//for Basic Auth, not in use yet.
private String basicAuthPass;
private String basicAuthPass4kermit = "Basic a2VybWl0Omtlcm1pdA==";
private String uniqueStr = createUniqueStrFromCurrentTime();//HHmmで一意文字列を生成する

private void execute() {
basicAuthPass = basicAuthPass4kermit;

try {
if (needExperiment) {
gotoLaboratory();
} else {
execWholeScenario();
}


} catch (URISyntaxException e) {
e.printStackTrace();
}
}

private static boolean needExperiment = true;

@SuppressWarnings("unchecked")
private void gotoLaboratory() throws URISyntaxException {
LinkedHashMap resBody;


startProcess("processDefinitionId", "oneTaskProcess:1:35");


}


@SuppressWarnings("unchecked")
private void execWholeScenario() throws URISyntaxException {
LinkedHashMap resBody;

// ■ ユーザ管理系
referUsers();
createUser("hoge" + uniqueStr);//Activitiのユーザテーブル登録時のPKとなる文字列を引数に指定する

// ■ プロセス制御系
int processInstanceId;
int activeProcessInstanceCount;

referProcessDefinitions();//既存プロセス定義の確認
resBody = referProcessInstances();//アクティブなプロセスの確認
activeProcessInstanceCount = Integer.parseInt(resBody.get("size").toString());
System.out.println(SIGN_MARKABLE_STATUS + activeProcessInstanceCount + " process(s) is(are) currently active.");

if (activeProcessInstanceCount == 0) {
//新規プロセスの開始 (ID指定)
startProcess("processDefinitionId", "oneTaskProcess:1:35");
resBody = referProcessInstances();//アクティブなプロセスの確認 >> 1つ増えている筈
activeProcessInstanceCount = Integer.parseInt(resBody.get("size").toString());
System.out.println(SIGN_MARKABLE_STATUS + activeProcessInstanceCount + " process(s) is(are) currently active.");
}

ArrayList activeProcessInstancesList = (ArrayList) resBody.get("data");
ArrayList activeProcessDefinitionKeyList = extractFromHashMapList(activeProcessInstancesList, "processDefinitionKey");
ArrayList activeProcessInstanceIdList = extractFromHashMapList(activeProcessInstancesList, "id");
processInstanceId = Integer.parseInt(activeProcessInstanceIdList.get(0));//whichever is fine. take 1st one.

// 特定プロセスインスタンスに対する操作
if (activeProcessDefinitionKeyList.contains("oneTaskProcess")) {
//プロセスインスタンスの一時停止・再開
referProcessInstance(processInstanceId);//特定プロセスの現状確認
suspendProcessInstance(processInstanceId);//特定プロセスの一時停止
referProcessInstance(processInstanceId);//確認
activateProcessInstance(processInstanceId);//特定プロセスの再開
//プロセスインスタンスの削除
resBody = referProcessInstances();//アクティブなプロセスの確認 >> 1つ増えている筈
activeProcessInstanceCount = Integer.parseInt(resBody.get("size").toString());
System.out.println(SIGN_MARKABLE_STATUS + activeProcessInstanceCount + " process(s) is(are) currently active.");
deleteProcessInstance(processInstanceId);//特定プロセスの削除
resBody = referProcessInstances();//アクティブなプロセスの確認 >> 1つ増えている筈
activeProcessInstanceCount = Integer.parseInt(resBody.get("size").toString());
System.out.println(SIGN_MARKABLE_STATUS + activeProcessInstanceCount + " process(s) is(are) currently active.");
//終了済みプロセスインスタンス一覧の照会
referHistoricProcessInstances();
}

if (activeProcessInstanceCount == 0) {
//新規プロセスの開始 (Key指定)
startProcess("processDefinitionKey", "oneTaskProcess");
resBody = referProcessInstances();//アクティブなプロセスの確認 >> 1つ増えている筈
activeProcessInstanceCount = Integer.parseInt(resBody.get("size").toString());
System.out.println(SIGN_MARKABLE_STATUS + activeProcessInstanceCount + " process(s) is(are) currently active.");
}

// ■ タスク制御
int activeTaskId;
//既存タスク一覧の照会
ArrayList activeTasksList = (ArrayList) referTasks().get("data");
ArrayList activeTasksIdList = extractFromHashMapList(activeTasksList, "id");
activeTaskId = Integer.parseInt(activeTasksIdList.get(0));
referTask(activeTaskId);//特定タスクの照会
completeTasks(activeTaskId);

}

private void completeTasks(int taskInstanceId) {
// TODO Auto-generated method stub

}

private void referTask(int taskInstanceId) throws URISyntaxException {
System.out.println(SIGN_METHOD_START + "SELECT A SPESIFIC TASK");
execRestGetCall(URL_RU_TASKS + "/" + taskInstanceId);
}

/**
* 既存タスクの照会
*
* @throws URISyntaxException
*/
private LinkedHashMap referTasks() throws URISyntaxException {
System.out.println(SIGN_METHOD_START + "SELECT ALL TASKS");
LinkedHashMap resBody = execRestGetCall(URL_RU_TASKS);
return resBody;
}

private void referHistoricProcessInstances() throws URISyntaxException {
System.out.println(SIGN_METHOD_START + "SELECT ALL HISTORIC PROCESS INSTANCES");
execRestGetCall(URL_HI_PROCESS_INSTANCES + "?finished=true");
}

private void deleteProcessInstance(int processInstanceId) throws URISyntaxException {
System.out.println(SIGN_METHOD_START + " DELETE A SPESIFIC PROCESS INSTANCE");
execRestDeleteCall(URL_RU_PROCESS_INSTANCES + "/" + processInstanceId);
}

private void activateProcessInstance(int processInstanceId) throws URISyntaxException {
System.out.println(SIGN_METHOD_START + " ACTIVATE A SPESIFIC PROCESS INSTANCE");

JSONObject reqBody = new JSONObject();
reqBody.put("action", "activate");

execRestPutCall(URL_RU_PROCESS_INSTANCES + "/" + processInstanceId, reqBody);
}

private void suspendProcessInstance(int processInstanceId) throws URISyntaxException {
System.out.println(SIGN_METHOD_START + " SUSPEND A SPESIFIC PROCESS INSTANCE");

JSONObject reqBody = new JSONObject();
reqBody.put("action", "suspend");

execRestPutCall(URL_RU_PROCESS_INSTANCES + "/" + processInstanceId, reqBody);
}


private ArrayList extractFromHashMapList(ArrayList activeProcessInstancesList, String keyStr) {
ArrayList valueList = new ArrayList<>();
for (LinkedHashMap processInstance : activeProcessInstancesList) {
valueList.add(processInstance.get(keyStr).toString());
}
return valueList;
}

private void referProcessInstance(int processInstanceId) throws URISyntaxException {
System.out.println(SIGN_METHOD_START + " SELECT A SPESIFIC PROCESS INSTANCE");
execRestGetCall(URL_RU_PROCESS_INSTANCES + "/" + processInstanceId);
}

/**
* 既存プロセスインスタンスの生成
*
* @throws URISyntaxException
*/
private LinkedHashMap referProcessInstances() throws URISyntaxException {
System.out.println(SIGN_METHOD_START + "SELECT ALL PROCESS INSTANCES");
LinkedHashMap resBody = execRestGetCall(URL_RU_PROCESS_INSTANCES);
return resBody;
}

/**
* 新規プロセスの開始
*
* @param specificValue
* @throws URISyntaxException
*/
private void startProcess(String specificKey, String specificValue) throws URISyntaxException {
System.out.println(SIGN_METHOD_START + "START A PROCESS");

JSONObject reqBody = new JSONObject();
reqBody.put(specificKey, specificValue);
reqBody.put("businessKey", "myBusinessKey");
JSONObject nestedVariables = new JSONObject();
nestedVariables.put("name", "myVar");
nestedVariables.put("value", "This is a variable");
JSONArray itemArray = new JSONArray();
itemArray.put(nestedVariables);
reqBody.put("variables", itemArray);

execRestPostCall(URL_RU_PROCESS_INSTANCES, reqBody);
}

/**
* 既存プロセス定義の照会
*
* @throws URISyntaxException
*/
private void referProcessDefinitions() throws URISyntaxException {
System.out.println(SIGN_METHOD_START + "SELECT ALL FROM PROCESS_DEFINITION TABLE");
execRestGetCall(URL_RE_PROCESS_DEFINITIONS);
}

/**
* 新規ユーザの登録
*
* @param primaryChar
* @throws URISyntaxException
*/
private void createUser(String primaryChar) throws URISyntaxException {
System.out.println(SIGN_METHOD_START + "INSERT A RECORD INTO USER TABLE");

JSONObject reqBody = new JSONObject();
reqBody.put("id", primaryChar);
reqBody.put("firstName", "Tijs");
reqBody.put("lastName", "Barrez");
reqBody.put("email", primaryChar + "@alfresco.org");
reqBody.put("password", "pass123");

execRestPostCall(URL_ID_USERS, reqBody);
}

@SuppressWarnings("unused")
private void createUser_bk(String primaryChar) throws URISyntaxException {
System.out.println(SIGN_METHOD_START + "INSERT A RECORD INTO USER TABLE");

String reqBody = "{"
+ "\"id\":\"" + primaryChar + "\","
+ "\"firstName\":\"Tijs\","
+ "\"lastName\":\"Barrez\","
+ "\"email\":\"" + primaryChar + "@alfresco.org\","
+ "\"password\":\"pass123\""
+ "}";

execRestPostCall(URL_ID_USERS, reqBody, null);
}

/**
* 既存ユーザの照会
*
* @throws URISyntaxException
*/
private void referUsers() throws URISyntaxException {
System.out.println(SIGN_METHOD_START + "SELECT ALL FROM USER TABLE");
execRestGetCall(URL_ID_USERS);
}

private void execRestPostCall(String requestPath, JSONObject reqBody) throws URISyntaxException {
execRestPostCall(requestPath, reqBody.toString(), reqBody);
}

private void execRestPostCall(String requestPath, String reqBodyStr, JSONObject reqBodyInJson4log) throws URISyntaxException {
@SuppressWarnings("unused")
String str4basicAuth = getStr4basicAuth();

// POST用の要求エンティティ
RequestEntity reqEntity = RequestEntity
.post(new URI(URL_ROOT + requestPath))
.header("Authorization", "Basic a2VybWl0Omtlcm1pdA==")
// .header("Authorization", str4basicAuth)
// .header("Authorization", "Basic " + str4basicAuth)//FIXME not sure why, doesnt work. needs the prefix??
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.body(reqBodyStr);

execRestCall(reqEntity, reqBodyInJson4log);
}

private LinkedHashMap execRestGetCall(String requestPath) throws URISyntaxException {
// GET用の要求エンティティ
RequestEntity reqEntity = RequestEntity
.get(new URI(URL_ROOT + requestPath))
.header("Authorization", basicAuthPass)
.accept(MediaType.APPLICATION_JSON)
.build();

return execRestCall(reqEntity, null);
}

private void execRestPutCall(String requestPath, JSONObject reqBody) throws URISyntaxException {
// PUT用の要求エンティティ
RequestEntity reqEntity = RequestEntity
.put(new URI(URL_ROOT + requestPath))
.header("Authorization", "Basic a2VybWl0Omtlcm1pdA==")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.body(reqBody.toString());

execRestCall(reqEntity, reqBody);

}

private void execRestDeleteCall(String requestPath) throws URISyntaxException {
// DELETE用の要求エンティティ
RequestEntity reqEntity = RequestEntity
.delete(new URI(URL_ROOT + requestPath))
.header("Authorization", basicAuthPass)
.accept(MediaType.APPLICATION_JSON)
.build();

execRestCall(reqEntity, null);
}

/**
* リクエストエンティティに沿ってREST通信し、取得した結果をコンソール出力する。
*
* @param reqEntity
* @param reqBodyInJson4log
* @throws URISyntaxException
*/
private LinkedHashMap execRestCall(RequestEntity reqEntity, JSONObject reqBodyInJson4log) throws URISyntaxException {
System.out.println("REQUEST:");
HttpHeaders reqHeaders = reqEntity.getHeaders();
System.out.println(reqHeaders.toString());
if (reqBodyInJson4log != null) System.out.println(reqBodyInJson4log.toString(4));
System.out.println();

ResponseEntity resEntity = restTemplate.exchange(reqEntity, Object.class);
System.out.println();

System.out.println("RESPONSE:");
HttpStatus statusCode = resEntity.getStatusCode();
System.out.println(statusCode);
HttpHeaders headers = resEntity.getHeaders();
System.out.println(headers);
Object body = resEntity.getBody();
System.out.println(body);
System.out.println();

if (body instanceof LinkedHashMap) {
System.out.print("formatting..\n");
Gson gson = new Gson();
String inJson = gson.toJson(body, LinkedHashMap.class);
JSONObject bodyInJson = new JSONObject(inJson);
System.out.println(bodyInJson.toString(4));
System.out.println();

return (LinkedHashMap) body;
}
return null;
}

private String createUniqueStrFromCurrentTime() {
SimpleDateFormat sdf = new SimpleDateFormat("HHmm");
Date date = new Date();
return sdf.format(date);
}

/**
* Basic認証用の文字列の生成
* @return
*/
private String getStr4basicAuth() {
byte[] bytes = (userId + ":" + userPw).getBytes();
return new String(Base64.encodeBase64(bytes));
// kermit:Kermit
// a2VybWl0Oktlcm1pdA== --> should be "Basic a2VybWl0Omtlcm1pdA=="
// gonzo:Gonzo
// Z29uem86R29uem8=
// fozzie:Fozzie
// Zm96emllOkZvenppZQ==

}

/**
* @param args
*/
public static void main(String[] args) {
TmpRestTestMain ttm = new TmpRestTestMain();
ttm.execute();

}


}

tag : Activiti REST RestTemplate BPMN gson JSON Java

2017-11-14 21:18 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] Activitiのデモアプリの休暇承認アプリを動かす


tag. Activiti Explorer BPMN

# 「Java Activiti Explorer - @//メモ - FrontPage」のまるコピ
# 本家が参照不能になってる為

Activiti-Explorer Getting Start †
http://www.activiti.org/download.html から activiti-5.18.0.zip をダウンロード
activiti-explorer.war を Glassfish 4.1 に配備
http://localhost:8080/activiti-explorer/

Sample User
User Id Password Security roles
kermit kermit admin
gonzo gonzo manager
fozzie fozzie user

休暇申請 †
fozzie (user) でログインして、プロセス→Vacation Request
プロセスを開始して、休暇申請を発行する
一件の休暇申請が承認待ち

承認 †
gonzo (manager) でログインすると、承認待ちが1件
Approve で受理

プロセス作成 †
kermit (admin) でログインする
プロセス → Model workspace で、プロセスを作ることができる

Activiti-Explorer の使い所 †
最初勘違いして混乱したんだけど、Activiti Explorer に個別実装を追加して個別アプリを仕立てるのではない
Activiti Explorer は、Activiti のデモの位置づけ
とはいえ非常によくできているので、マスターメンテアプリとして使おう

Activiti Explorer ができること
-Tasks ワークフローの実行
-Process プロセスの管理
-Reporting レポート作成
-Manage データベースのメンテ

Manage
-生テーブルの閲覧
BPMNの配備
-JOB管理 (各プロセスのタイマー待ちの管理など)
-User管理/Group管理

個別アプリは Activiti Engine をライブラリとして組み込んで作成する
-個別アプリからは Activiti Engine の API を通してワークフローDBを操作する
-その他に業務のデータベースを持つ。休暇申請のワークフローは Activiti の Workflow Database で管理されるが、勤怠や給与なんかは個別アプリ側の Database で管理する

その他に Activiti Rest が提供されていて、こいつは Workflow を REST-API から操作できるようにするもの

ワークフロー情報の格納先を Postgres に変更する †
デフォルト設定では H2 のインメモリデータベースに、ワークフローデータを格納している (プロセスを落とすと消えてしまう)
利用できるデータベース
-database type url
-h2 jdbc:h2:tcp://localhost/activiti
-mysql jdbc:mysql://localhost:3306/activiti?autoReconnect=true
-oracle jdbc:oracle:thin:@localhost:1521:xe
-postgres jdbc:postgresql://localhost:5432/activiti
-db2 jdbc:db2://localhost:50000/activiti
-mssql jdbc:sqlserver://localhost:1433;databaseName=activiti
-jdbc:jtds:sqlserver://localhost:1433/activiti

今回は、Postgres に格納するように変更する
格納先データベースを作成
[~]$ createuser -P activiti
Enter password for new role: activiti_password
Enter it again: activiti_password
[~]$ createdb -E UTF-8 -O activiti -U atsushi activiti
activiti-explorer.war を展開して
JDBC ドライバを /WEB-INF/lib に配置する
https://jdbc.postgresql.org/download.html

DEMOデータの設定
/WEB-INF/classes/engine.properties
# demo data properties
create.demo.users=true
create.demo.definitions=true
create.demo.models=true
create.demo.reports=true

# engine properties
engine.schema.update=true
engine.activate.jobexecutor=false
engine.asyncexecutor.enabled=true
engine.asyncexecutor.activate=true
engine.history.level=full

# email properties
#engine.email.enabled=true
#engine.email.host=localhost
#engine.email.port=1025

tomcatの再起動ごとにデモデータが追加されるので、一度だけこの設定で起動して、以降は domo.create.* を全部 false にする必要あり

データベース接続の設定
/WEB-INF/classes/db.properties
#db=h2
#jdbc.driver=org.h2.Driver
#jdbc.url=jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000
#jdbc.username=sa
#jdbc.password=

db=postgres
jdbc.driver=org.postgresql.Driver
jdbc.url=jdbc:postgresql://localhost:5432/activiti
jdbc.username=activiti
jdbc.password=activiti_password

ディレクトリ指定で配備
[注意] URL Context Root) は、必ず activiti-explorer にする。コード内に絶対パスで指定している所あり
普通に使える
Posgres の activiti データベースに、Activiti サンプルができている

再び war に圧縮するときには、圧縮対象のディレクトリに入るのがミソ
$ export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/
$ cd activiti-explorer
$ jar cf ../activiti-explorer.war .

プロセス図示のAPI †
http://localhost:8080/activiti-explorer/diagram-viewer/index.html?processDefinitionId=reviewSaledLead:1:36
http://localhost:8080/activiti-explorer/diagram-viewer/index.html?processDefinitionId=reviewSaledLead:1:36&processInstanceId=41

無効化したい場合は、ui.properties の activiti.ui.jsdiagram = false (デフォルトtrue)

Reporting †
上部メニューのHistory からレポートを作ことができる
History level は none 以上にする必要あり
WEB-INF/classes/engine.properties
engine.history.level=full

対応しているグラフ
-pieChart
-lineChart
-barChart
-list

レポート作成プログラムの登録
普通の BPMN [Start -> Task -> End] を登録すればよい
ただし、ROOT要素 <'definitions> の targetNamespace には activiti-report を設定する
<'?xml version="1.0" encoding="UTF-8"?>
<'definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"
  xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"
  xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema"
  expressionLanguage="http://www.w3.org/1999/XPath"
  targetNamespace="activiti-report">

  <'process id="process-instance-overview-report" name="Process Instance Overview" isExecutable="true">
    ...
  <'/process>
<'/definitions>

プロセスが終了したときに、グラフ表示するデータが格納された JSON をバイト配列でプロセス変数 reportData に格納しておくと、そのデータがグラフとして表示される
execution.setVariable(
"reportData"
, new java.lang.String(Jackson.objectMapper.writeValueAsString(bean)).getBytes("UTF-8"));

グラフデータの形式
{
  "title": "My Report",
  "datasets": [
    {
      "type" : "lineChart",
      "description" : "My first chart",
      "xaxis" : "Year"
      "yaxis" : "Total sales"
      "data" :
      {
        "2010" : 50,
        "2011" : 33,
        "2012" : 17,
        "2013" : 87,
      }
    }
  ]
}
typeに設定できるのは、pieChart, lineChart, barChart and list.

通常の Process 同様に <'startEvent> に Form を作ることができる
<'startEvent id="startevent1" name="Start">
  <'extensionElements>
    <'activiti:formProperty id="processDefinition" name="Select process definition" type="processDefinition" required="true" />
    <'activiti:formProperty id="chartType" name="Chart type" type="enum" required="true">
      <'activiti:value id="pieChart" name="Pie chart" />
      <'activiti:value id="barChart" name="Bar chart" />
    <'/activiti:formProperty>
  <'/extensionElements>
<'/startEvent>

ref.
Java Activiti Explorer - @//メモ - FrontPage, 2016/12/18
https://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwig-PLz7rzXAhVDwbwKHWesBWgQFggmMAA&url=https%3A%2F%2Fhondou.homedns.org%2Fpukiwiki%2Fpukiwiki.php%3FJava%2520Activiti%2520Explorer&usg=AOvVaw2qah7jPizDWkt37fN0kHNe

tag : Activiti Explorer BPMN

2017-11-14 21:14 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] Activitiのいろいろもろもろのまとめ - 入口

いろいろもろもろのまとめ as-of 20171110
Activiti ver.6.0.0

## そもそも Activiti とは --------------------
ワークフローアプリ向けライブラリ群
色々とワークフローアプリ/システムが出回っているが、内部でこのActivitiを使用している説あり - e.g. intra-mart
流行り?のBPMN(ビジネスプロセスモデリング表記法)にも対応しているのも人気の一因?

Alfresco社が発起人で現在もサポートしている。
提供しているActivitiは有償版と無償版の二つ
ココでは、無償版 Activiti v6.0.0 を対象に情報をまとめる

無償版 Activiti v6.0.0 に含まれるデモアプリ(サンプルアプリ)がある
それを動かして Activiti を理解するのがゴール

☆キーワード☆
ワークフロー
BPMN

ref.
https://www.activiti.org
https://www.activiti.org/userguide/index.html


## おおまかに Activiti 操作の一連の流れ --------------------
用語の概念を掴んだ者がActiviti制す
なので、関連用語を折り込みつつ一連の流れの話

STEP 00
対象にする任意の業務を1つ特定する

STEP 01
その業務の作業プロ―(業務フロー、ワークフロー、フロー、業務プロセスプロセス)を整理する。※ Activiti の Process と Model の違い - 要勉強★TODO
その作業フローを文面にする=業務プロ―定義、ワークフロー定義、フロー定義、プロセス定義
文面化する際に用いるルールがBPMN
1つ業務フローは複数のタスク(アクション)から成立する。※ Activiti の Task と Form の違い - 要勉強★TODO

STEP 02
そのワークフローをシステムで管理する為のアプリ(システム)を作成する
i.e. AAAさん担当のタスクが発生したらAAAさんにメールが自動送信され、AAAさんが作業完了をそのシステムに連携すると次のタスクに遷移する、みたいな。
そのシステムを実装する時に Activiti のライブラリを使う → ワークフローシステム とする
ワークフローシステムをサーバにデプロイしたら運用開始

STEP 03
先の STEP 01 で文面化したプロセス定義を ワークフローシステム に読み込ませる = Activiti の管理テーブルに登録する
この行為は、デプロイ(もしくはパブリッシュ)と呼ばれる
基本的に1回のみの行為。
プロセス(作業フロー)を改める時に改めてデプロイすることになる = Activiti の管理テーブルに登録した情報を更新する

STEP 04
プロセスを開始する。=プロセスの生成、プロセスインスタンスの生成
例えば、「月次勤務報告書の作成」という業務フローであれば月次で対象プロセスを新規に開始させる。

STEP 05
当該プロセスインスタンスのタスクを順次に完了させる。
最後のタスクが完了するとそのプロセス(プロセスインスタン)が完了したことになる

## Activiti 資材の入手 --------------------
以下よりダウンロード
Activiti Source Code Download (Activiti-activiti-6.0.0.zip)
https://github.com/Activiti/Activiti/archive/activiti-6.0.0.zip
# ビルド済みのwarでやる場合:
# コンテキストパスなどが自分でビルドする場合(上記のzipでやる場合)と異なるので要注意
# Activiti Download (activiti-6.0.0.zip)
# https://github.com/Activiti/Activiti/releases/download/activiti-6.0.0/activiti-6.0.0.zip

zipを展開すると大量のプロジェクトがお目見えする。
大きく以下のように分類できる
BPMN関連*
Form関連
DMN関連*
REST関連
-その他

|三大モデリング標準
|→ BPMN(about processing)、DMN(about managing)、CMMN(about deciding)

|* BPMN
|Business Process Modeling Notation
|ビジネス・プロセスを記述する表記法

|* DMN
|Decision Model and Notation
|Object Management Group(OMG)が提案する標準モデリングルール

|* CMMN
|Case Management Model and Notation

|ref.
|BPMN-CMMN-DMN An intro to the triple crown of process improvement standards Denis Gagne -- ☆オススメ
|https://www.slideshare.net/dgagne/bpmncmmndmn-an-intro-to-the-triple-crown-of-process-improvement-standards-denis-gagne/9
|IBM Blueworks Liveによるビジネス・ルールのモデリング
|https://www.ibm.com/developerworks/jp/websphere/library/bpm/bwl_brm/

BPMN関連に分類される以下のプロジェクトが主たるもの
他は全部サンプル!
-activiti-bpmn-model
-activiti-process-validation
-activiti-image-generator
-activiti-bpmn-layout
-activiti-bpmn-converter
-activiti-json-converter
-activiti-engine
-activiti-spring
# FORM系の扱いはちょっと微妙かも-要勉強★TODO

ざっくりプロジェクト関係
トップ来るのがmodel
modelを参照する子世代が、converter、validation、layout達
modelから見て孫世代に当たるのが engine で、子世代のプロジェクトを参照する

サンプルの中でも王道サンプルが3つ
-activiti-admin > 複数のワークフローシステムを束ねるサンプルアプリ?
-activiti-app > Webブラウザ越しにワークフローの定義や実行ができるWebアプリ
-activiti-webapp-rest2 > REST通信でリクエストを受け付けるサーバアプリ

|余談:Googleでよく見かける activiti-explorer と activiti-app に関して

|activiti-explorer
|管理者向けアプリで v5.22 まで存在した。
|プロセス定義のみならずActivitiの管理テーブルの参照も可能にする万能Webアプリ
|https://mvnrepository.com/artifact/org.activiti/activiti-explorer
|v6.0.0 より登場した activiti-admin がそれに替わるものなのか?-確認中★TODO
|https://mvnrepository.com/artifact/org.activiti/activiti-admin

|activiti-app
|v6.0.0 (released on May 25, 2017) からお目見えしたサンプルWebアプリ
|サンプルアプリであって管理者向けアプリではない。完全に別物。
|プロセス定義やワークフロー操作は可能だがDB参照はできない
|https://mvnrepository.com/artifact/org.activiti/activiti-app
|https://mvnrepository.com/artifact/org.activiti/activiti-engine/6.0.0

|ref.
|Activiti日本語情報ブログ
|http://lalalafrance.hatenablog.com/entry/2016/03/22/073945
|Activiti Release History
|https://github.com/Activiti/Activiti/releases

参考:
activiti 界隈の登場人物
https://docs.alfresco.com/activiti/docs/admin-guide/1.5.0/images/high-level-architecture.png
ref.
ACTIVITI ADMIN GUIDE
Version 1.5.0, August 2016
https://docs.alfresco.com/activiti/docs/admin-guide/1.5.0/


## Activiti デモアプリの動作確認 (activiti-webapp-rest2) --------------------
STEP 01
定義されたプロセスの有無確認
プロセス定義の確認(ワークフローシステムにデプロイされたフロー定義の有無)
GET     /repository/process-definitions

→ 結果にて、実行させたいプロセスのID(もしくはKey)を確認

STEP 02
実行中のプロセスの確認(開始済み・未完了のプロセスインスタンスの確認)
GET     /runtime/process-instances

STEP 03
そのプロセスの実行(プロセスインスタンスの生成、プロセスの開始)
POST    /runtime/process-instances      13.5.4. Start a process instance
http://localhost:8081/activiti-webapp-rest2/service/runtime/process-instances
Method: POST
Authorization:  Basic a2VybWl0Omtlcm1pdA==
Content-Type:   application/json
Accept: application/json
Request body (start by process definition id):
|{
|   "processDefinitionId":"oneTaskProcess:1:35",
|   "businessKey":"myBusinessKey",
|   "variables": [
|      {
|        "name":"myVar",
|        "value":"This is a variable"
|      }
|   ]
|}
※ processDefinitionId は、前段で確認した文字列に変更すること

STEP 04
実行中のプロセスの確認(開始済み・未完了のプロセスインスタンスの確認)
GET     /runtime/process-instances
→ プロセスの実行前と比較して増えている筈


## Activiti デモアプリの動作確認 (activiti-app) --------------------




## Activiti デモアプリの動作確認 (activiti-admin) --------------------
いろいろ憶測:
activiti-app なりと別にデプロイされる想定のアプリ
管理者が以下管理コンソールにログインし、任意の操作を行う
http://localhost:8081/activiti-admin/
ログイン認証は、activiti-webapp-rest2.war (activiti-rest.war) なり activiti-app.war なりと通信して行う(後者のみかも)
つまり、それらアプリの認証権限のあるuserでないとログインできない(のかな?)
→ app, webapp-rest2, admin 全部デプロイして admin/test で試みたがやはりログインできない。。

それらアプリとの通信の設定が定義されているのが以下のファイル
/activiti-admin/src/main/resources/META-INF/activiti-admin/activiti-admin.properties
デフォルト:
# REST endpoint config
rest.app.name=Activiti app
rest.app.description=Activiti app Rest config
rest.app.host=http://localhost
rest.app.port=9999
rest.app.contextroot=activiti-app
rest.app.restroot=api
rest.app.user=admin
rest.app.password=test


|脱線
|1. activiti-app の接続先DBの変更
|1-1. /activiti-app/src/main/resources/META-INF/activiti-app/activiti-app.properties
|datasource.driver=org.h2.Driver
|datasource.url=jdbc:h2:mem:activiti;DB_CLOSE_DELAY=-1
|datasource.username=sa
|datasource.password=
|hibernate.dialect=org.hibernate.dialect.H2Dialect
|## for PostgreSQL
|#datasource.driver=org.postgresql.Driver
|#datasource.url=jdbc:postgresql://127.0.0.1:5432/activiti
|#datasource.username=admin
|#datasource.password=P@ssword
|#hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
|## for H2
|datasource.driver=org.h2.Driver
|datasource.url=jdbc:h2:mem:activiti;DB_CLOSE_DELAY=-1
|datasource.username=sa
|datasource.password=
|hibernate.dialect=org.hibernate.dialect.H2Dialect
|1-2. /activiti-app/pom.xml
|               
|                       com.h2database
|                       h2
|               

|               
|2. activiti-webapp-rest2 の接続先DBの変更
|2-1. /activiti-webapp-rest2/src/main/resources/db.properties
|2-2. /activiti-webapp-rest2/pom.xml




## Activiti の 登場人物 (調査中) --------------------
Forms
業務プロセスでマニュアルの工程を入れる時に使用する。
フレキシブルに追加できる
実現情報は2つ:
- Build-in form redering with form properties
- external form rendering
cf.
https://www.activiti.org/userguide/index.html?_ga=2.257356418.843444075.1507187930-1788343053.1507187930#forms

tag : Activiti プロセス モデル Form BPMN DMN REST

2017-11-10 22:11 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] Activitiの登場人物の概念が知りたい

tag. Activiti BPM BPMN RuntimeService TaskService IdentityService ManagementService HistoryService ProcessEngineConfiguration

■ 細胞核となるのはプロセスエンジン - ProcessEngine
ClassDoc曰く
BPMとワークフローに関する処理を提供する。
-org.activiti.engine.RuntimeService: Deployment の生成、開始と、ProcessInstances の開始、検索をする
-org.activiti.engine.TaskService: 各タスクを独立的に操作する。タスクのクレーム、完了、割振りなど
-org.activiti.engine.IdentityService: ユーザとグループを管理する
-org.activiti.engine.ManagementService: エンジンの管理とメンテ操作
-org.activiti.engine.HistoryService: 現在進行中と完了済みのプロセス情報の操作
1つのアプリに1つはプロセスエンジンが必要。
プロセスエンジンは ProcessEngineConfiguration で生成されること。
性能を下げない為に無暗な生成は回避すべき

プロセスエンジンが内容するサービスたち = Activitiの登場人物

RepositoryService
  プロセス定義とデプロイのリポジトリの操作
RuntimeService
  (憶測) 現状のプロセス状況を管理
FormService
  プロセスインスタンスの開始やタスクの終了の為の form の操作
TaskService
  task と form 関連の操作
HistoryService
  進行中と過去のプロセスインスタンス情報の参照。
  runtime と区別すること。runtime は、その時点でのruntimeの状態のみを保持し、
  runtime processの実行に最適化されている。対し、History は永続情報の参照に最適化されている。
IdentityService
  ユーザとグループの管理
ManagementService
  エンジンの管理とメンテ操作。
  ワークフロー駆動アプリでは基本使用されない。管理コンソールで使用されるもの。
DynamicBpmnService
  RepositoryService と同等の役割
FormRepositoryService
  form のリポジトリ操作
org.activiti.form.api.FormService
  ??

以下、気になったとこだけ抜粋

■ RepositoryService
  -#createDeployment
  -#deploy
  -#deleteDeployment
  -#createDeploymentQuery
  -#suspendProcessDefinitionByXxx
  -#activateProcessDefinitionByXxx
  -#setProcessDefinitionCategory
  -#getProcessModel
  -#getProcessDefinition
  -#getBpmnModel
  -#newModel
  -#saveModel
  -#deleteModel
  -#getModel
  -#validateProcess
  cf.
  DeployCmd, SuspendProcessDefinitionCmd, ActivateProcessDefinitionCmd, CreateModelCmd, etc.

RuntimeService
  -#startProcessInstanceByXxx
  -#addParticipantUser/Group
  cf.
  StartProcessInstanceCmd, DeleteProcessInstanceCmd

■ FormService
  -#getTaskFormData
  -#submitTaskFormData
  -#saveFormData

TaskService

HistoryService
  -#createHistoricProcessInstanceQuery
  -#createHistoricTaskInstanceQuery
  -#deleteHistoricTaskInstance
  -#deleteHistoricProcessInstance

IdentityService

ManagementService
  -#createJobQuery
  -#executeJob
  -#deleteJob

■ DynamicBpmnService

■ FormRepositoryService
  -#createDeployment
  -#deleteDeployment
  -#createFormQuery

■ org.activiti.form.api.FormService



Activiti User Guide の REST 章 の記載事項
https://www.activiti.org/userguide/index.html?_ga=2.257356418.843444075.1507187930-1788343053.1507187930#_rest_api

13.1. General Activiti REST principles
13.2. Deployment
13.3. Process Definitions
13.4. Models
13.5. Process Instances
13.6. Executions
13.7. Tasks
13.8. History
13.9. Forms
13.10. Database tables
13.11. Engine
13.12. Runtime
13.13. Jobs
13.14. Users
13.15. Groups


■ Web UI からやったこと:
ユーザ1を作成
ユーザ2を作成
プロセスの作成(=モデルの新規定義)
アプリの作成
アプリのプロセスの紐づけ設定
アプリのパブリッシュ
プロセスインスタンスの開始

tag : Activiti BPM BPMN RuntimeService TaskService IdentityService ManagementService HistoryService ProcessEngineConfiguration

2017-11-10 22:09 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] Activitiの公式ガイドには無いRESTリクエスト一覧

tag. Activiti BPMN REST rest activiti GET POST PUT DELETE

Activiti User Guide に記載ないけど、実在するRESTのリクエストの一覧
as of 20171110
Activiti v6.0.0
ref.
https://www.activiti.org/userguide/index.html?_ga=2.257356418.843444075.1507187930-1788343053.1507187930#_rest_api

--------------------
# Tab-Sepalated Values (TSV) for pasting on SpreadSheet

project HTTP Method Path
activiti-admin GET /rest/activiti/apps/{appId}
activiti-admin DELETE /rest/activiti/apps/{appId}
activiti-admin GET /rest/activiti/app
activiti-admin GET /rest/activiti/apps/process-definitions/{deploymentId}
activiti-admin GET /rest/activiti/apps/decision-tables/{dmnDeploymentId}
activiti-admin GET /rest/activiti/apps/forms/{appDeploymentId}
activiti-admin GET /rest/activiti/apps/export/{deploymentId}
activiti-admin GET /rest/activiti/apps/redeploy/{deploymentId}
activiti-admin GET /rest/activiti/apps/redeploy/{deploymentId}/{replaceAppId}
activiti-admin N/A /rest/activiti/apps
activiti-admin GET /rest/activiti/apps
activiti-admin POST /rest/activiti/apps
activiti-admin GET /rest/activiti/decision-tables/{decisionTableId}
activiti-admin GET /rest/activiti/decision-tables/{decisionTableId}/editorJson
activiti-admin GET /rest/activiti/decision-tables
activiti-admin GET /rest/activiti/process-definition-decision-tables/{processDefinitionId}
activiti-admin GET /rest/activiti/deployments/{deploymentId}
activiti-admin DELETE /rest/activiti/deployments/{deploymentId}
activiti-admin N/A /rest/activiti/deployments
activiti-admin GET /rest/activiti/deployments
activiti-admin POST /rest/activiti/deployments
activiti-admin GET /rest/activiti/process-definitions/{processDefinitionId}/model-json
activiti-admin GET /rest/activiti/process-instances/{processInstanceId}/model-json
activiti-admin GET /rest/activiti/forms/{formId}
activiti-admin GET /rest/activiti/forms/{formId}/editorJson
activiti-admin GET /rest/activiti/process-definition-start-form/{processDefinitionId}
activiti-admin GET /rest/activiti/forms
activiti-admin GET /rest/activiti/process-definition-forms/{processDefinitionId}
activiti-admin GET /rest/activiti/jobs/{jobId}
activiti-admin DELETE /rest/activiti/jobs/{jobId}
activiti-admin POST /rest/activiti/jobs/{jobId}
activiti-admin GET /rest/activiti/jobs/{jobId}/stacktrace
activiti-admin GET /rest/activiti/jobs
activiti-admin N/A /rest/activiti/models
activiti-admin GET /rest/activiti/models
activiti-admin GET /rest/activiti/process-definitions/{definitionId}
activiti-admin PUT /rest/activiti/process-definitions/{definitionId}
activiti-admin GET /rest/activiti/process-definitions/{definitionId}/process-instances
activiti-admin GET /rest/activiti/process-definitions/{definitionId}/jobs
activiti-admin GET /rest/activiti/process-definitions
activiti-admin GET /rest/activiti/engine-info
activiti-admin GET /rest/activiti/process-instances/{processInstanceId}
activiti-admin GET /rest/activiti/process-instances/{processInstanceId}/tasks
activiti-admin GET /rest/activiti/process-instances/{processInstanceId}/variables
activiti-admin PUT /rest/activiti/process-instances/{processInstanceId}/variables/{variableName}
activiti-admin POST /rest/activiti/process-instances/{processInstanceId}/variables
activiti-admin DELETE /rest/activiti/process-instances/{processInstanceId}/variables/{variableName}
activiti-admin GET /rest/activiti/process-instances/{processInstanceId}/subprocesses
activiti-admin GET /rest/activiti/process-instances/{processInstanceId}/jobs
activiti-admin POST /rest/activiti/process-instances/{processInstanceId}
activiti-admin POST /rest/activiti/process-instances
activiti-admin GET /rest/activiti/submitted-forms
activiti-admin GET /rest/activiti/form-submitted-forms/{formId}
activiti-admin GET /rest/activiti/task-submitted-form/{taskId}
activiti-admin GET /rest/activiti/process-submitted-forms/{processId}
activiti-admin GET /rest/activiti/submitted-forms/{submittedFormId}
activiti-admin GET /rest/activiti/tasks/{taskId}
activiti-admin DELETE /rest/activiti/tasks/{taskId}
activiti-admin POST /rest/activiti/tasks/{taskId}
activiti-admin PUT /rest/activiti/tasks/{taskId}
activiti-admin GET /rest/activiti/tasks/{taskId}/subtasks
activiti-admin GET /rest/activiti/tasks/{taskId}/variables
activiti-admin GET /rest/activiti/tasks/{taskId}/identitylinks
activiti-admin POST /rest/activiti/tasks
activiti-admin GET /rest/authenticate
activiti-admin GET /rest/account
activiti-admin GET /rest/server-configs
activiti-admin GET /rest/server-configs/default
activiti-admin PUT /rest/server-configs/{serverId}
activiti-admin GET /rest/users/{login}
activiti-admin PUT /rest/users/{login}
activiti-admin PUT /rest/users/{login}/change-password
activiti-admin DELETE /rest/users/{login}
activiti-admin GET /rest/users
activiti-admin POST /rest/users
activiti-app-rest GET /rest/app-definitions/{modelId}
activiti-app-rest GET /rest/app-definitions/{modelId}/history/{modelHistoryId}
activiti-app-rest PUT /rest/app-definitions/{modelId}
activiti-app-rest POST /rest/app-definitions/{modelId}/publish
activiti-app-rest GET /rest/app-definitions/{modelId}/export
activiti-app-rest POST /rest/app-definitions/{modelId}/import
activiti-app-rest POST /rest/app-definitions/{modelId}/text/import
activiti-app-rest POST /rest/app-definitions/import
activiti-app-rest POST /rest/app-definitions/text/import
activiti-app-rest N/A /rest/decision-table-models
activiti-app-rest GET /values
activiti-app-rest GET /{decisionTableId}
activiti-app-rest GET /{decisionTableId}/export
activiti-app-rest POST /import-decision-table
activiti-app-rest POST /import-decision-table-text
activiti-app-rest GET /history/{historyModelId}
activiti-app-rest GET /history/{historyModelId}/export
activiti-app-rest PUT /{decisionTableId}
activiti-app-rest N/A /rest/decision-table-models
activiti-app-rest GET /rest/models/{processModelId}/model-json
activiti-app-rest GET /rest/models/{processModelId}/history/{processModelHistoryId}/model-json
activiti-app-rest GET /rest/editor-groups
activiti-app-rest N/A /rest/form-models
activiti-app-rest GET /{formId}
activiti-app-rest GET /values
activiti-app-rest GET /{formId}/history/{formHistoryId}
activiti-app-rest PUT /{formId}
activiti-app-rest N/A /rest/form-models
activiti-app-rest GET /rest/models/{processModelId}/bpmn20
activiti-app-rest GET /rest/models/{processModelId}/history/{processModelHistoryId}/bpmn20
activiti-app-rest GET /rest/models/{modelId}/history
activiti-app-rest GET /rest/models/{modelId}/history/{modelHistoryId}
activiti-app-rest POST /rest/models/{modelId}/history/{modelHistoryId}
activiti-app-rest GET /rest/models/{modelId}/parent-relations
activiti-app-rest GET /rest/models/{modelId}
activiti-app-rest GET /rest/models/{modelId}/thumbnail
activiti-app-rest PUT /rest/models/{modelId}
activiti-app-rest DELETE /rest/models/{modelId}
activiti-app-rest GET /rest/models/{modelId}/editor/json
activiti-app-rest POST /rest/models/{modelId}/editor/json
activiti-app-rest POST /rest/models/{modelId}/newversion
activiti-app-rest GET /rest/models
activiti-app-rest GET /rest/models-for-app-definition
activiti-app-rest POST /rest/import-process-model
activiti-app-rest POST /rest/import-process-model/text
activiti-app-rest POST /rest/models
activiti-app-rest POST /rest/models/{modelId}/clone
activiti-app-rest GET /rest/stencil-sets/editor
activiti-app-rest GET /rest/authenticate
activiti-app-rest GET /rest/account
activiti-app-rest N/A /rest/admin/groups
activiti-app-rest GET /{groupId}
activiti-app-rest GET /{groupId}/users
activiti-app-rest PUT /{groupId}
activiti-app-rest DELETE /{groupId}
activiti-app-rest POST /{groupId}/members/{userId}
activiti-app-rest DELETE /{groupId}/members/{userId}
activiti-app-rest N/A /rest/admin
activiti-app-rest GET /profile
activiti-app-rest POST /profile
activiti-app-rest POST /profile-password
activiti-app-rest GET /profile-picture
activiti-app-rest POST /profile-picture
activiti-app-rest GET /rest/admin/users
activiti-app-rest PUT /rest/admin/users/{userId}
activiti-app-rest PUT /rest/admin/users
activiti-app-rest DELETE /rest/admin/users/{userId}
activiti-app-rest POST /rest/admin/users
activiti-app-rest GET /rest/users/{userId}
activiti-app-rest GET /rest/runtime/app-definitions
activiti-app-rest GET /rest/runtime/app-definitions/{deploymentKey}
activiti-app-rest GET /rest/tasks/{taskId}/comments
activiti-app-rest POST /rest/tasks/{taskId}/comments
activiti-app-rest GET /rest/process-instances/{processInstanceId}/comments
activiti-app-rest POST /rest/process-instances/{processInstanceId}/comments
activiti-app-rest POST /rest/query/history/tasks
activiti-app-rest GET /rest/process-definitions/{processDefinitionId}/start-form
activiti-app-rest GET /rest/process-definitions
activiti-app-rest POST /rest/query/process-instances
activiti-app-rest GET /rest/process-instances/{processInstanceId}
activiti-app-rest GET /rest/process-instances/{processInstanceId}/start-form
activiti-app-rest DELETE /rest/process-instances/{processInstanceId}
activiti-app-rest POST /rest/process-instances
activiti-app-rest GET /rest/tasks/{taskId}/content
activiti-app-rest GET /rest/process-instances/{processInstanceId}/content
activiti-app-rest GET /rest/content/{source}/{sourceId}/process-instances
activiti-app-rest POST /rest/tasks/{taskId}/raw-content
activiti-app-rest POST /rest/tasks/{taskId}/raw-content/text
activiti-app-rest POST /rest/tasks/{taskId}/content
activiti-app-rest POST /rest/processes/{processInstanceId}/content
activiti-app-rest POST /rest/process-instances/{processInstanceId}/raw-content
activiti-app-rest POST /rest/process-instances/{processInstanceId}/raw-content/text
activiti-app-rest POST /rest/content/raw
activiti-app-rest POST /rest/content/raw/text
activiti-app-rest POST /rest/content
activiti-app-rest DELETE /rest/content/{contentId}
activiti-app-rest GET /rest/content/{contentId}
activiti-app-rest GET /rest/content/{contentId}/raw
activiti-app-rest GET /rest/process-instances/{processInstanceId}/model-json
activiti-app-rest GET /rest/process-definitions/{processDefinitionId}/model-json
activiti-app-rest GET /rest/process-instances/history/{processInstanceId}/model-json
activiti-app-rest PUT /rest/tasks/{taskId}/action/complete
activiti-app-rest PUT /rest/tasks/{taskId}/action/assign
activiti-app-rest PUT /rest/tasks/{taskId}/action/involve
activiti-app-rest PUT /rest/tasks/{taskId}/action/remove-involved
activiti-app-rest PUT /rest/tasks/{taskId}/action/claim
activiti-app-rest N/A /rest/task-forms
activiti-app-rest GET /{taskId}
activiti-app-rest POST /{taskId}
activiti-app-rest GET /{taskId}/variables
activiti-app-rest POST /rest/query/tasks
activiti-app-rest GET /rest/tasks/{taskId}
activiti-app-rest PUT /rest/tasks/{taskId}
activiti-app-rest POST /rest/tasks
activiti-app-rest GET /rest/workflow-users
activiti-dmn-rest POST /rules/decision-executor
activiti-dmn-rest GET /dmn-repository/decision-tables
activiti-dmn-rest GET /dmn-repository/decision-tables/{decisionTableId}/model
activiti-dmn-rest GET /dmn-repository/decision-tables/{decisionTableId}
activiti-dmn-rest GET /dmn-repository/decision-tables/{decisionTableId}/resourcedata
activiti-dmn-rest GET /dmn-repository/deployments
activiti-dmn-rest POST /dmn-repository/deployments
activiti-dmn-rest GET /dmn-repository/deployments/{deploymentId}
activiti-dmn-rest DELETE /dmn-repository/deployments/{deploymentId}
activiti-dmn-rest GET /dmn-repository/deployments/{deploymentId}/resourcedata/{resourceId}
activiti-rest PUT /runtime/executions
activiti-rest GET /runtime/executions/{executionId}/variables
activiti-rest DELETE /runtime/executions/{executionId}/variables
activiti-rest GET /runtime/executions/{executionId}/variables/{variableName}/data
activiti-rest GET /runtime/executions/{executionId}/variables/{variableName}
activiti-rest DELETE /runtime/executions/{executionId}/variables/{variableName}
activiti-rest GET /runtime/process-instances/{processInstanceId}/identitylinks/users/{identityId}/{type}
activiti-rest DELETE /runtime/process-instances/{processInstanceId}/identitylinks/users/{identityId}/{type}
activiti-rest DELETE /runtime/process-instances/{processInstanceId}/variables
activiti-rest GET /runtime/process-instances/{processInstanceId}/variables/{variableName}/data
activiti-rest DELETE /runtime/process-instances/{processInstanceId}/variables/{variableName}
activiti-rest GET /runtime/tasks/{taskId}/attachments/{attachmentId}/content
activiti-rest POST /runtime/tasks
activiti-rest DELETE /runtime/tasks/{taskId}/events/{eventId}
activiti-rest GET /runtime/tasks/{taskId}/identitylinks/{family}
activiti-rest DELETE /runtime/tasks/{taskId}
activiti-rest GET /runtime/tasks/{taskId}/subtasks
activiti-rest GET /runtime/tasks/{taskId}/variables
activiti-rest GET /runtime/tasks/{taskId}/variables/{variableName}/data
activiti-rest GET /runtime/tasks/{taskId}/variables/{variableName}
activiti-rest DELETE /runtime/tasks/{taskId}/variables/{variableName}
activiti-rest GET /history/historic-process-instances/{processInstanceId}/identitylinks
activiti-rest GET /history/historic-task-instances/{taskId}/identitylinks
activiti-rest DELETE /identity/groups/{groupId}/members/{userId}
activiti-rest DELETE /identity/groups/{groupId}
activiti-rest GET /identity/users/{userId}/info
activiti-rest DELETE /identity/users/{userId}/info/{key}
activiti-rest GET /identity/users/{userId}/picture
activiti-rest PUT /identity/users/{userId}/picture
activiti-rest DELETE /identity/users/{userId}
activiti-rest GET /management/deadletter-jobs
activiti-rest GET /management/jobs/{jobId}/exception-stacktrace
activiti-rest GET /management/timer-jobs/{jobId}/exception-stacktrace
activiti-rest GET /management/suspended-jobs/{jobId}/exception-stacktrace
activiti-rest GET /management/deadletter-jobs/{jobId}/exception-stacktrace
activiti-rest GET /management/timer-jobs/{jobId}
activiti-rest GET /management/suspended-jobs/{jobId}
activiti-rest GET /management/deadletter-jobs/{jobId}
activiti-rest DELETE /management/jobs/{jobId}
activiti-rest DELETE /management/timer-jobs/{jobId}
activiti-rest DELETE /management/deadletter-jobs/{jobId}
activiti-rest POST /management/jobs/{jobId}
activiti-rest GET /management/suspended-jobs
activiti-rest GET /management/timer-jobs
activiti-rest GET /repository/deployments/{deploymentId}/resourcedata/{resourceName}
activiti-rest DELETE /repository/models/{modelId}
activiti-rest GET /repository/models/{modelId}/source-extra
activiti-rest PUT /repository/models/{modelId}/source-extra
activiti-rest GET /repository/models/{modelId}/source
activiti-rest PUT /repository/models/{modelId}/source
activiti-rest DELETE /repository/process-definitions/{processDefinitionId}/identitylinks/{family}/{identityId}
activiti-rest GET /repository/process-definitions/{processDefinitionId}/image
activiti-rest GET /repository/process-definitions/{processDefinitionId}/resourcedata
spring-boot-starters GET /processes/{processDefinitionKey:.*}

tag : Activiti BPMN REST rest activiti GET POST PUT DELETE

2017-11-10 22:07 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] Activitiのプロセス開始の裏側の調査

■ お題
プロセス開始の裏側の調査

■ 記録
Activiti v6.0.0 / activiti-webapp-rest2 をサーバにデプロイして起動

process-instance」をRequestMappingに持つRestControllerの一覧
project package Class
activiti-admin  com.activiti.web.rest.client    DisplayJsonClientResource.java (2 matches)
activiti-admin  com.activiti.web.rest.client    ProcessDefinitionClientResource.java (4 matches)
activiti-admin  com.activiti.web.rest.client    ProcessInstanceClientResource.java (9 matches)
activiti-admin  com.activiti.web.rest.client    ProcessInstancesClientResource.java
activiti-app-rest       org.activiti.app.rest.runtime   CommentsResource.java (4 matches)
activiti-app-rest       org.activiti.app.rest.runtime   ProcessInstanceQueryResource.java
activiti-app-rest       org.activiti.app.rest.runtime   ProcessInstanceResource.java (3 matches)
activiti-app-rest       org.activiti.app.rest.runtime   ProcessInstancesResource.java
activiti-app-rest       org.activiti.app.rest.runtime   RelatedContentResource.java (15 matches)
activiti-app-rest       org.activiti.app.rest.runtime   RuntimeDisplayJsonClientResource.java (3 matches)
activiti-rest   org.activiti.rest.service.api.runtime.process   ProcessInstanceCollectionResource.java (2 matches)
activiti-rest   org.activiti.rest.service.api.runtime.process   ProcessInstanceDiagramResource.java
activiti-rest   org.activiti.rest.service.api.runtime.process   ProcessInstanceIdentityLinkCollectionResource.java (2 matches)
activiti-rest   org.activiti.rest.service.api.runtime.process   ProcessInstanceIdentityLinkResource.java (2 matches)
activiti-rest   org.activiti.rest.service.api.runtime.process   ProcessInstanceResource.java (3 matches)
activiti-rest   org.activiti.rest.service.api.runtime.process   ProcessInstanceVariableCollectionResource.java (4 matches)
activiti-rest   org.activiti.rest.service.api.runtime.process   ProcessInstanceVariableDataResource.java
activiti-rest   org.activiti.rest.service.api.runtime.process   ProcessInstanceVariableResource.java (3 matches)

プロセスインスタンス生成・開始後であれば上記リストから始めれば良い。
が、そもそもサンプルにモデルプロセスがあるのかどうか。。
なので、User GuideにあるRequest Mappingを抽出、以下を実行し既存するモデルプロセスの有無を確認

GET     /repository/process-definitions ― ★
cf.
activiti-rest
org.activiti.rest.service.api.repository
ProcessDefinitionCollectionResource.java

実行結果
{"data":[{"id":"createTimersProcess:1:36","url":"http://localhost:8081/activiti-webapp-rest2/service/repository/process-definitions/createTimersProcess:1:36",...

これを Eclipse (STS) の任意のJSONファイルに張り付け、
ファイルのコンテキストメニュー>ソース>フォーマットで整形した結果
cf.
shortcut key: CTRL + SHIFT + F for Format
shortcut key: CTRL + SHIFT + G for Compress
ref.
Eclipseを使ってJSONデータを整形する
https://qiita.com/ken_ue/items/57af40649ee727ef68d1

|{
|       "data": [
|               {
|                       "id": "createTimersProcess:1:36",
|                       "url": "http://localhost:8081/activiti-webapp-rest2/service/repository/process-definitions/createTimersProcess:1:36",
|                       "key": "createTimersProcess",
|                       "version": 1,
|                       "name": "Create timers process",
|                       "description": "Test process to create a number of timers.",
|                       "tenantId": "",
|                       "deploymentId": "20",
|                       "deploymentUrl": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20",
|                       "resource": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resources/createTimersProcess.bpmn20.xml",
|                       "diagramResource": null,
|                       "category": "Examples",
|                       "graphicalNotationDefined": false,
|                       "suspended": false,
|                       "startFormDefined": false
|               },
|               {
|                       "id": "oneTaskProcess:1:35",
|                       "url": "http://localhost:8081/activiti-webapp-rest2/service/repository/process-definitions/oneTaskProcess:1:35",
|                       "key": "oneTaskProcess",
|                       "version": 1,
|                       "name": "Famous One Task Process",
|                       "description": null,
|                       "tenantId": "",
|                       "deploymentId": "20",
|                       "deploymentUrl": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20",
|                       "resource": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resources/oneTaskProcess.bpmn20.xml",
|                       "diagramResource": null,
|                       "category": "Examples",
|                       "graphicalNotationDefined": false,
|                       "suspended": false,
|                       "startFormDefined": false
|               },
|               {
|                       "id": "fixSystemFailure:1:32",
|                       "url": "http://localhost:8081/activiti-webapp-rest2/service/repository/process-definitions/fixSystemFailure:1:32",
|                       "key": "fixSystemFailure",
|                       "version": 1,
|                       "name": "Fix system failure",
|                       "description": null,
|                       "tenantId": "",
|                       "deploymentId": "20",
|                       "deploymentUrl": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20",
|                       "resource": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resources/FixSystemFailureProcess.bpmn20.xml",
|                       "diagramResource": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resources/FixSystemFailureProcess.png",
|                       "category": "Examples",
|                       "graphicalNotationDefined": false,
|                       "suspended": false,
|                       "startFormDefined": false
|               },
|               {
|                       "id": "escalationExample:1:34",
|                       "url": "http://localhost:8081/activiti-webapp-rest2/service/repository/process-definitions/escalationExample:1:34",
|                       "key": "escalationExample",
|                       "version": 1,
|                       "name": "Helpdesk process",
|                       "description": null,
|                       "tenantId": "",
|                       "deploymentId": "20",
|                       "deploymentUrl": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20",
|                       "resource": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resources/Helpdesk.bpmn20.xml",
|                       "diagramResource": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resources/Helpdesk.png",
|                       "category": "Examples",
|                       "graphicalNotationDefined": false,
|                       "suspended": false,
|                       "startFormDefined": false
|               },
|               {
|                       "id": "reviewSaledLead:1:33",
|                       "url": "http://localhost:8081/activiti-webapp-rest2/service/repository/process-definitions/reviewSaledLead:1:33",
|                       "key": "reviewSaledLead",
|                       "version": 1,
|                       "name": "Review sales lead",
|                       "description": null,
|                       "tenantId": "",
|                       "deploymentId": "20",
|                       "deploymentUrl": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20",
|                       "resource": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resources/reviewSalesLead.bpmn20.xml",
|                       "diagramResource": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resources/reviewSalesLead.reviewSaledLead.png",
|                       "category": "Examples",
|                       "graphicalNotationDefined": true,
|                       "suspended": false,
|                       "startFormDefined": false
|               },
|               {
|                       "id": "vacationRequest:1:31",
|                       "url": "http://localhost:8081/activiti-webapp-rest2/service/repository/process-definitions/vacationRequest:1:31",
|                       "key": "vacationRequest",
|                       "version": 1,
|                       "name": "Vacation request",
|                       "description": null,
|                       "tenantId": "",
|                       "deploymentId": "20",
|                       "deploymentUrl": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20",
|                       "resource": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resources/VacationRequest.bpmn20.xml",
|                       "diagramResource": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resources/VacationRequest.png",
|                       "category": "http://activiti.org/bpmn20",
|                       "graphicalNotationDefined": false,
|                       "suspended": false,
|                       "startFormDefined": false
|               }
|       ],
|       "total": 6,
|       "start": 0,
|       "sort": "name",
|       "order": "asc",
|       "size": 6
|}

つまり、以下の 6つ 既存しているらしい
"Create timers process"
"Famous One Task Process"
"Fix system failure"
"Helpdesk process"
"Review sales lead"
"Vacation request"
同定義は、以下の物理ファイルからも確認できる
/activiti-webapp-rest2/src/main/resources/createTimersProcess.bpmn20.xml
/activiti-webapp-rest2/src/main/resources/oneTaskProcess.bpmn20.xml
/activiti-webapp-rest2/src/main/resources/FixSystemFailureProcess.bpmn20.xml
/activiti-webapp-rest2/src/main/resources/Helpdesk.bpmn20.xml
/activiti-webapp-rest2/src/main/resources/reviewSalesLead.bpmn20.xml
/activiti-webapp-rest2/src/main/resources/VacationRequest.bpmn20.xml


|ちょっと脱線
|元データの在り処が知りたい

|以下を実行
|GET    /management/tables
|どのテーブルが目星を付けられない

|ならば、RestControllerから
|activiti-rest
|org.activiti.rest.service.api.repository
|ProcessDefinitionCollectionResource.java
|EntityManagerまで行き着かない

|ならば、MyBatis の SQL 定義ファイルから
|SQLを参照するに以下のテーブルを照会している
|-ACT_RE_PROCDEF
|-ACT_RU_EVENT_SUBSCR

|cf.
|MyBatis:
|/activiti-engine/src/main/resources/org/activiti/db/mapping/entity/ProcessDefinition.xml
|select id="selectProcessDefinitionsByQueryCriteria"
|include refid="selectProcessDefinitionsByQueryCriteriaSql"


RESTでテーブルのデータ確認
|/management/tables/{tableName}/data
|/management/tables/ACT_RE_PROCDEF/data
|/management/tables/ACT_RU_EVENT_SUBSCR/data

|結果 - ACT_RE_PROCDEF - 6 record
|{
|       "data": [
|               {
|                       "DGRM_RESOURCE_NAME_": "VacationRequest.png",
|                       "KEY_": "vacationRequest",
|                       "HAS_GRAPHICAL_NOTATION_": false,
|                       "ID_": "vacationRequest:1:31",
|                       "DEPLOYMENT_ID_": "20",
|                       "CATEGORY_": "http://activiti.org/bpmn20",
|                       "TENANT_ID_": "",
|                       "VERSION_": 1,
|                       "SUSPENSION_STATE_": 1,
|                       "HAS_START_FORM_KEY_": false,
|                       "REV_": 1,
|                       "RESOURCE_NAME_": "VacationRequest.bpmn20.xml",
|                       "NAME_": "Vacation request"
|               },
|               {
|                       "DGRM_RESOURCE_NAME_": "FixSystemFailureProcess.png",
|                       "KEY_": "fixSystemFailure",
|                       "HAS_GRAPHICAL_NOTATION_": false,
|                       "ID_": "fixSystemFailure:1:32",
|                       "DEPLOYMENT_ID_": "20",
|                       "CATEGORY_": "Examples",
|                       "TENANT_ID_": "",
|                       "VERSION_": 1,
|                       "SUSPENSION_STATE_": 1,
|                       "HAS_START_FORM_KEY_": false,
|                       "REV_": 1,
|                       "RESOURCE_NAME_": "FixSystemFailureProcess.bpmn20.xml",
|                       "NAME_": "Fix system failure"
|               },
|               {
|                       "DGRM_RESOURCE_NAME_": "reviewSalesLead.reviewSaledLead.png",
|                       "KEY_": "reviewSaledLead",
|                       "HAS_GRAPHICAL_NOTATION_": true,
|                       "ID_": "reviewSaledLead:1:33",
|                       "DEPLOYMENT_ID_": "20",
|                       "CATEGORY_": "Examples",
|                       "TENANT_ID_": "",
|                       "VERSION_": 1,
|                       "SUSPENSION_STATE_": 1,
|                       "HAS_START_FORM_KEY_": false,
|                       "REV_": 1,
|                       "RESOURCE_NAME_": "reviewSalesLead.bpmn20.xml",
|                       "NAME_": "Review sales lead"
|               },
|               {
|                       "DGRM_RESOURCE_NAME_": "Helpdesk.png",
|                       "KEY_": "escalationExample",
|                       "HAS_GRAPHICAL_NOTATION_": false,
|                       "ID_": "escalationExample:1:34",
|                       "DEPLOYMENT_ID_": "20",
|                       "CATEGORY_": "Examples",
|                       "TENANT_ID_": "",
|                       "VERSION_": 1,
|                       "SUSPENSION_STATE_": 1,
|                       "HAS_START_FORM_KEY_": false,
|                       "REV_": 1,
|                       "RESOURCE_NAME_": "Helpdesk.bpmn20.xml",
|                       "NAME_": "Helpdesk process"
|               },
|               {
|                       "KEY_": "oneTaskProcess",
|                       "VERSION_": 1,
|                       "HAS_GRAPHICAL_NOTATION_": false,
|                       "ID_": "oneTaskProcess:1:35",
|                       "SUSPENSION_STATE_": 1,
|                       "HAS_START_FORM_KEY_": false,
|                       "REV_": 1,
|                       "RESOURCE_NAME_": "oneTaskProcess.bpmn20.xml",
|                       "DEPLOYMENT_ID_": "20",
|                       "CATEGORY_": "Examples",
|                       "NAME_": "Famous One Task Process",
|                       "TENANT_ID_": ""
|               },
|               {
|                       "KEY_": "createTimersProcess",
|                       "HAS_GRAPHICAL_NOTATION_": false,
|                       "ID_": "createTimersProcess:1:36",
|                       "DEPLOYMENT_ID_": "20",
|                       "CATEGORY_": "Examples",
|                       "TENANT_ID_": "",
|                       "VERSION_": 1,
|                       "SUSPENSION_STATE_": 1,
|                       "HAS_START_FORM_KEY_": false,
|                       "REV_": 1,
|                       "DESCRIPTION_": "Test process to create a number of timers.",
|                       "RESOURCE_NAME_": "createTimersProcess.bpmn20.xml",
|                       "NAME_": "Create timers process"
|               }
|       ],
|       "total": 6,
|       "start": 0,
|       "sort": null,
|       "order": null,
|       "size": 6
|}

|結果 - ACT_RU_EVENT_SUBSCR - 0 record
|{"data":[],"total":0,"start":0,"sort":null,"order":null,"size":0}


次に既存するプロセスインスタンス有無の確認
以下を実行
GET     /runtime/process-instances ― ★
cf.
activiti-rest
org.activiti.rest.service.api.runtime.process
ProcessInstanceCollectionResource.java (2 matches)

結果
|{
|"data": [],
|"total": 0,
|"start": 0,
|"sort": "id",
|"order": "asc",
|"size": 0
|}


いざ、プロセス開始
POST    /runtime/process-instances ― ★
13.5.4. Start a process instance
http://localhost:8081/activiti-webapp-rest2/service/runtime/process-instances
Method: POST
Authorization:  Basic a2VybWl0Omtlcm1pdA==
Content-Type:   application/json
Accept: application/json

cf.
activiti-rest
org.activiti.rest.service.api.runtime.process
ProcessInstanceCollectionResource.java (2 matches)
REST API Authorization
http://docs.alfresco.com/process-services1.6/topics/rest_api_authorization.html

User Guideにある通りにリクエストボディを入力
Request body (start by process definition id):
※ 以下の Payload は、Response Code 400 で失敗する (後述参照)
| 1{
| 2   "processDefinitionId":"oneTaskProcess:1:158",
| 3   "businessKey":"myBusinessKey",
| 4   "variables": [
| 5      {
| 6        "name":"myVar",
| 7        "value":"This is a variable",
| 8      }
| 9   ]
|10}

実行結果 - ERROR
|400 Bad Request
|{
|"message": "Bad request",
|"exception": "Could not read document: Unexpected character ('}' (code 125)): was expecting double-quote to start field name at [Source: java.io.PushbackInputStream@e7d3329; line: 8, column: 8] at [Source: java.io.PushbackInputStream@e7d3329; line: 7, column: 17] (through reference chain: org.activiti.rest.service.api.runtime.process.ProcessInstanceCreateRequest["variables"]->java.util.ArrayList[0]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Unexpected character ('}' (code 125)): was expecting double-quote to start field name at [Source: java.io.PushbackInputStream@e7d3329; line: 8, column: 8] at [Source: java.io.PushbackInputStream@e7d3329; line: 7, column: 17] (through reference chain: org.activiti.rest.service.api.runtime.process.ProcessInstanceCreateRequest["variables"]->java.util.ArrayList[0])"
|}

Could not read document:
Unexpected character ('}' (code 125)): was expecting double-quote to start field name
at [Source: java.io.PushbackInputStream@e7d3329; line: 8, column: 8]
at [Source: java.io.PushbackInputStream@e7d3329; line: 7, column: 17]
(through reference chain: org.activiti.rest.service.api.runtime.process.ProcessInstanceCreateRequest["variables"]->java.util.ArrayList[0]);

ref.
System.JSONException: Unexpected character ('}' (code 125))
https://salesforce.stackexchange.com/questions/167877/system-jsonexception-unexpected-character-code-125

Payload の 7 行目の "value":"This is a variable",
の後のカンマが不要

| 1{
| 2 "processDefinitionId":"oneTaskProcess:1:158",
| 3 "businessKey":"myBusinessKey",
| 4 "variables": [
| 5 {
| 6 "name":"myVar",
| 7 "value":"This is a variable"
| 8 }
| 9 ]
|10}

実行結果 - ERROR
|{
| "message": "Bad request",
| "exception": "no deployed process definition found with id 'oneTaskProcess:1:158'"
|}

ref.
https://github.com/Activiti/Activiti/blob/master/activiti-engine/src/test/java/org/activiti/engine/test/api/runtime/RuntimeServiceTest.java
| public void testStartProcessInstanceByIdUnexistingId() {
| try {
| runtimeService.startProcessInstanceById("unexistingId");
| fail("ActivitiException expected");
| } catch (ActivitiObjectNotFoundException ae) {
| assertTextPresent("no deployed process definition found with id",
| ae.getMessage());
| assertEquals(ProcessDefinition.class,
| ae.getObjectClass());
| }
| }

grep with "no deployed process definition found with id"
org.activiti.engine.impl.persistence.deploy.DeploymentManager#findDeployedProcessDefinitionById
| if (processDefinition == null) {
| processDefinition = processDefinitionEntityManager.findById(processDefinitionId);
| if (processDefinition == null) {
| throw new ActivitiObjectNotFoundException("no deployed process definition found with id '" + processDefinitionId + "'", ProcessDefinition.class);
| }
| processDefinition = resolveProcessDefinition(processDefinition).getProcessDefinition();
| }


processDefinition = oneTaskProcess:1:158
という名称でデプロイされていないのが原因

デプロイされているプロセスの確認
GET /repository/deployments - ★
cf.
Chap. 13.2.1. List of Deployments
activiti-rest
org.activiti.rest.service.api.repository
DeploymentCollectionResource.java
DataResponse #getDeployments

http://localhost:8081/activiti-webapp-rest2/service/repository/deployments
Method: GET
Authorization: Basic a2VybWl0Omtlcm1pdA==
Accept: application/json

実行結果
|{
| "data": [
| {
| "id": "20",
| "name": "Demo processes",
| "deploymentTime": "2017-11-10T10:11:36.909+09:00",
| "category": null,
| "url": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20",
| "tenantId": ""
| }
| ],
| "total": 1,
| "start": 0,
| "sort": "id",
| "order": "asc",
| "size": 1
|}

→ 開始しようとしているプロセスがデプロイされていない?

プロセスを新規にデプロイしたい
デプロイは多分パブリッシュと同義

以下のRESTリクエストパスは新規にプロセスをアップロードする行為なので、多分ちがう
POST /repository/deployments
cf.
activiti-rest
org.activiti.rest.service.api.repository
DeploymentCollectionResource.java
Activiti User Guide Chap. 13.2.3. Create a new deployment

プロセスを新規にデプロイするためのRESTリクエストパスが知りたい

activiti-app を Webブラウザから、
モデル・アプリを作成した時に更新されたテーブル:
 -ACT_DE_MODEL
 -ACT_DE_MODEL_RELATION
アプリを公開した時に更新されたテーブル:
 -ACT_DE_MODEL_HISTORY
 -ACT_GE_BYTEARRAY
 -ACT_RE_DEPLOYMENT
 -ACT_RE_PROCDEF

ACT_GE_BYTEARRAY にinsertしているSQLを以下からgrep
/activiti-engine/src/main/resources/org/activiti/db/mapping/entity/

一番、目ぼしい奴
/activiti-engine/src/main/resources/org/activiti/db/mapping/entity/ByteArray.xml

| insert into ${prefix}ACT_GE_BYTEARRAY(ID_, REV_, NAME_, BYTES_, DEPLOYMENT_ID_)
| values (
| #{id, jdbcType=VARCHAR},
| 1,
| #{name, jdbcType=VARCHAR},
| #{bytes, jdbcType=${blobType}},
| #{deploymentId, jdbcType=VARCHAR}
| )


[insertByteArray](引用符なし)でgrepしてもhitせず
ByteArrayEntityImpl impl ByteArrayEntity
[ByteArrayEntity ](半角スペース終わり)でのgrep結果もピンと来ない

ならば、
ACT_RE_DEPLOYMENT にinsertしているSQLを以下からgrep
/activiti-engine/src/main/resources/org/activiti/db/mapping/entity/

一番、目ぼしい奴
/activiti-engine/src/main/resources/org/activiti/db/mapping/entity/Deployment.xml

| insert into ${prefix}ACT_RE_DEPLOYMENT(ID_, NAME_, CATEGORY_, KEY_, TENANT_ID_, DEPLOY_TIME_, ENGINE_VERSION_)
| values(#{id, jdbcType=VARCHAR}, #{name, jdbcType=VARCHAR}, #{category, jdbcType=VARCHAR}, #{key, jdbcType=VARCHAR}, #{tenantId, jdbcType=VARCHAR}, #{deploymentTime, jdbcType=TIMESTAMP}, #{engineVersion, jdbcType=VARCHAR})


DeploymentEntityImpl impl DeploymentEntity
[DeploymentEntity ](半角スペース終わり)でのgrep結果で目ぼしい奴、3クラス
DeployCmd.java (6 matches)
 - protected Deployment executeDeploy(CommandContext commandContext)
 - protected void scheduleProcessDefinitionActivation(CommandContext commandContext, DeploymentEntity deployment)
Deployer.java ← impl by RulesDeployer, BpmnDeployer
 - void deploy(DeploymentEntity deployment, Map deploymentSettings);
DeploymentManager.java (4 matches)
 - public void deploy(DeploymentEntity deployment, Map deploymentSettings) → deployer.deploy(deployment, deploymentSettings);

DeployCmd#executeDeploy から逆引き
RepositoryServiceImpl
 - public Deployment deploy(DeploymentBuilderImpl deploymentBuilder)
[.deploy();]でのgrepで目ぼしい奴
activiti-rest:
DeploymentCollectionResource.java
 - 169: Deployment deployment = deploymentBuilder.deploy();
activiti-spring:
DefaultAutoDeploymentStrategy.java
 - 63: deploymentBuilder.deploy();
ResourceParentFolderAutoDeploymentStrategy.java
 - 76: deploymentBuilder.deploy();
SingleResourceAutoDeploymentStrategy.java
 - 62: deploymentBuilder.deploy();
activiti-webapp-rest2
DemoDataConfiguration.java
 - 159: .deploy();

DemoDataConfiguration
| protected void initDemoProcessDefinitions() {

| String deploymentName = "Demo processes";
| List deploymentList = repositoryService.createDeploymentQuery().deploymentName(deploymentName).list();

| if (deploymentList == null || deploymentList.isEmpty()) {
| repositoryService.createDeployment().name(deploymentName).addClasspathResource("createTimersProcess.bpmn20.xml").addClasspathResource("oneTaskProcess.bpmn20.xml")
| .addClasspathResource("VacationRequest.bpmn20.xml").addClasspathResource("VacationRequest.png").addClasspathResource("FixSystemFailureProcess.bpmn20.xml")
| .addClasspathResource("FixSystemFailureProcess.png").addClasspathResource("Helpdesk.bpmn20.xml").addClasspathResource("Helpdesk.png").addClasspathResource("reviewSalesLead.bpmn20.xml")
| .deploy();
| }
| }

GET http://localhost:8081/activiti-webapp-rest2/service/repository/deployments の結果 (再掲)
"id": "20",
"name": "Demo processes",

上記の2点から考察するに
-DemoDataConfiguration#initDemoProcessDefinitions
-GET repository/deployments

Demo processes というデプロイ操作名称で、以下のサンプルモデルがすべてデプロイ済み、ということか?
"Create timers process"
"Famous One Task Process"
"Fix system failure"
"Helpdesk process"
"Review sales lead"
"Vacation request"

デプロイ詳細の確認
GET /repository/deployments/{deploymentId} - ★
http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20
activiti-rest
org.activiti.rest.service.api.repository
DeploymentResource.java
13.2.2. Get a deployment

実行結果
/repository/deployments の結果にidフィルタが掛かっただけ

既存モデルの確認
GET /repository/models - ★
http://localhost:8081/activiti-webapp-rest2/service/repository/models
activiti-rest
org.activiti.rest.service.api.repository
ModelCollectionResource.java
13.4.1. Get a list of models

実行結果
|{
| "data": [
| {
| "name": "Demo model",
| "key": null,
| "category": null,
| "version": 1,
| "metaInfo": "{"name":"Demomodel","description":"Thisisademomodel"}",
| "deploymentId": null,
| "tenantId": "",
| "id": "37",
| "url": "http://localhost:8081/activiti-webapp-rest2/service/repository/models/37",
| "createTime": "2017-11-10T10:11:37.628+09:00",
| "lastUpdateTime": "2017-11-10T10:11:37.644+09:00",
| "deploymentUrl": null,
| "sourceUrl": "http://localhost:8081/activiti-webapp-rest2/service/repository/models/37/source",
| "sourceExtraUrl": "http://localhost:8081/activiti-webapp-rest2/service/repository/models/37/source-extra"
| }
| ],
| "total": 1,
| "start": 0,
| "sort": "id",
| "order": "asc",
| "size": 1
|}

結局デプロイされているの?されてないの?

デプロイリソースの確認
GET /repository/deployments/{deploymentId}/resources/** - ★
http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resources/
13.2.6. Get a deployment resource
activiti-rest org.activiti.rest.service.api.repository
DeploymentResourceResource.java

実行結果[
| {
| "id": "FixSystemFailureProcess.bpmn20.xml",
| "url": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resources/FixSystemFailureProcess.bpmn20.xml",
| "contentUrl": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resourcedata/FixSystemFailureProcess.bpmn20.xml",
| "mediaType": "text/xml",
| "type": "processDefinition"
| },
| {
| "id": "FixSystemFailureProcess.png",
| "url": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resources/FixSystemFailureProcess.png",
| "contentUrl": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resourcedata/FixSystemFailureProcess.png",
| "mediaType": "image/png",
| "type": "resource"
| },
| {
| "id": "Helpdesk.bpmn20.xml",
| "url": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resources/Helpdesk.bpmn20.xml",
| "contentUrl": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resourcedata/Helpdesk.bpmn20.xml",
| "mediaType": "text/xml",
| "type": "processDefinition"
| },
| {
| "id": "Helpdesk.png",
| "url": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resources/Helpdesk.png",
| "contentUrl": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resourcedata/Helpdesk.png",
| "mediaType": "image/png",
| "type": "resource"
| },
| {
| "id": "VacationRequest.bpmn20.xml",
| "url": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resources/VacationRequest.bpmn20.xml",
| "contentUrl": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resourcedata/VacationRequest.bpmn20.xml",
| "mediaType": "text/xml",
| "type": "processDefinition"
| },
| {
| "id": "VacationRequest.png",
| "url": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resources/VacationRequest.png",
| "contentUrl": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resourcedata/VacationRequest.png",
| "mediaType": "image/png",
| "type": "resource"
| },
| {
| "id": "createTimersProcess.bpmn20.xml",
| "url": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resources/createTimersProcess.bpmn20.xml",
| "contentUrl": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resourcedata/createTimersProcess.bpmn20.xml",
| "mediaType": "text/xml",
| "type": "processDefinition"
| },
| {
| "id": "oneTaskProcess.bpmn20.xml",
| "url": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resources/oneTaskProcess.bpmn20.xml",
| "contentUrl": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resourcedata/oneTaskProcess.bpmn20.xml",
| "mediaType": "text/xml",
| "type": "processDefinition"
| },
| {
| "id": "reviewSalesLead.bpmn20.xml",
| "url": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resources/reviewSalesLead.bpmn20.xml",
| "contentUrl": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resourcedata/reviewSalesLead.bpmn20.xml",
| "mediaType": "text/xml",
| "type": "processDefinition"
| },
| {
| "id": "reviewSalesLead.reviewSaledLead.png",
| "url": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resources/reviewSalesLead.reviewSaledLead.png",
| "contentUrl": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resourcedata/reviewSalesLead.reviewSaledLead.png",
| "mediaType": "image/png",
| "type": "resource"
| }
|]

ref.
Dealing with Activiti through REST, Raka Cokorda, 2014/09/29
https://www.youtube.com/watch?v=yynfYadc0ZI

結論
☆ デプロイ=Activitiの管理テーブルに登録すること
☆ プロセスの開始は、processDefinitionId もしくは processDefinitionKey を指定して行う
※ プロセスを開始する場合は、その前にプロセスを定義をデプロイしていること
※ processDefinitionId / processDefinitionKey は、GET http://localhost:8081/activiti-webapp-rest2/service/repository/process-definitions で確認できる
※ もしくは ACT_RE_PROCDEF テーブルを確認する
☆ プロセスの開始は、/service/runtime/process-instances でできる

REST要求必須ヘッダの認証情報
activiti-webapp-rest2に事前登録されているユーザとパスワードををコロン ":" でつなぎ、Base64でエンコードしたものを指定すれば良い (Basic認証)
※ 既存するデモユーザは/activiti-webapp-rest2/src/main/java/org/activiti/rest/conf/DemoDataConfiguration#initDemoUsersで確認できる
※ デモユーザ"kermit"でactiviti-webapp-rest2を操作する場合 Basic a2VybWl0Omtlcm1pdA== となる

既存するプロセス定義の確認
GET     /repository/process-definitions ― ★ (再掲)

実行結果
| {
| "id": "oneTaskProcess:1:35",
| "url": "http://localhost:8081/activiti-webapp-rest2/service/repository/process-definitions/oneTaskProcess:1:35",
| "key": "oneTaskProcess",
| "version": 1,
| "name": "Famous One Task Process",
| "description": null,
| "tenantId": "",
| "deploymentId": "20",
| "deploymentUrl": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20",
| "resource": "http://localhost:8081/activiti-webapp-rest2/service/repository/deployments/20/resources/oneTaskProcess.bpmn20.xml",
| "diagramResource": null,
| "category": "Examples",
| "graphicalNotationDefined": false,
| "suspended": false,
| "startFormDefined": false
| },

プロセスの新規開始
POST /runtime/process-instances 13.5.4. Start a process instance ― ★
http://localhost:8081/activiti-webapp-rest2/service/runtime/process-instances
Method: POST
Authorization: Basic a2VybWl0Omtlcm1pdA==
Content-Type: application/json
Accept: application/json
Request body (start by process definition id):
| 1{
| 2 "processDefinitionId":"oneTaskProcess:1:35",
| 3 "businessKey":"myBusinessKey",
| 4 "variables": [
| 5 {
| 6 "name":"myVar",
| 7 "value":"This is a variable"
| 8 }
| 9 ]
|10}
※ processDefinitionId が登録した(デプロイした)定義情報と等しいこと

実行結果
|{
| "id": "40",
| "url": "http://localhost:8081/activiti-webapp-rest2/service/runtime/process-instances/40",
| "businessKey": "myBusinessKey",
| "suspended": false,
| "ended": false,
| "processDefinitionId": "oneTaskProcess:1:35",
| "processDefinitionUrl": "http://localhost:8081/activiti-webapp-rest2/service/repository/process-definitions/oneTaskProcess:1:35",
| "processDefinitionKey": "oneTaskProcess",
| "activityId": null,
| "variables": [],
| "tenantId": "",
| "name": null,
| "completed": false
|}

開始されているプロセスインスタンスの確認
GET /runtime/process-instances ― ★ (再掲)
http://localhost:8081/activiti-webapp-rest2/service/runtime/process-instances

実行結果
|{
| "data": [
| {
| "id": "40",
| "url": "http://localhost:8081/activiti-webapp-rest2/service/runtime/process-instances/40",
| "businessKey": "myBusinessKey",
| "suspended": false,
| "ended": false,
| "processDefinitionId": "oneTaskProcess:1:35",
| "processDefinitionUrl": "http://localhost:8081/activiti-webapp-rest2/service/repository/process-definitions/oneTaskProcess:1:35",
| "processDefinitionKey": "oneTaskProcess",
| "activityId": null,
| "variables": [],
| "tenantId": "",
| "name": null,
| "completed": false
| }
| ],
| "total": 1,
| "start": 0,
| "sort": "id",
| "order": "asc",
| "size": 1
|}

以下でも特定プロセスの状態を確認できる
GET http://localhost:8081/activiti-webapp-rest2/service/runtime/process-instances?id=40&includeProcessValiables=true

tag : BPMN Activiti process-instance repository REST

2017-11-09 21:23 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] Activiti の user 管理を制御するクラスたち

tag. Activiti BPM BPMN v6.0.0 UserResource UserCollectionResource UserInfoResource UserInfoCollectionResource UserPictureResource IDM SSO

Activiti の user 管理系の処理
=Request URL が 「/identity/users」で始まるもの

■ 制御クラスは大きく3種類
プロジェクト activiti-rest の パッケージ org.activiti.rest.service.api.identity にある以下のクラスたち
UserResource ( バルク操作の場合 → UserCollectionResource )
UserInfoResource ( バルク操作の場合 → UserInfoCollectionResource )
UserPictureResource

上記を和文にすると
ユーザ管理 (特定1ユーザ)  ユーザ管理 (バルク)
ユーザ詳細/URL (特定1ユーザ)      ユーザ詳細/URL (バルク)
ユーザ詳細/画像 (特定1ユーザ)
※ 便宜上、実装に沿ってURLとしたが実際はMapで変数指定するぽい。

UserResource で使用するBean/Entity は UserResponse
UserResponse が保持する fields は以下の通り
① id
② firstName
③ lastName
④ passWord
⑤ email
⑥ url
⑦ pictureUrl

この内の ⑥ url に特化して操作するのが UserInfoResource で、
また、⑦ pictureUrl に特化しているのが UserPictureResource
他の ①~⑤に特化しているのが user 管理の中でも核になる UserResource
だと思われる
この UserResource の操作が ACT_ID_USER と対になる
のだろう

cf.
user 管理で使用される table である ACT_ID_USER のカラム構成:
id_
rev_
first_
last_
email_
pwd_
picture_id_

■ シングル操作とバルク操作
1 user に対して処理する場合と、複数 user に対して同時に処理する場合で制御クラスが異なる
# エクセルに張り付けて見て。
# 制御クラス名、CRUD区分、メソッドの順で掲載してる

#       シングル操作                  バルク操作
1       UserResource    [C]     N/A     UserCollectionResource  [C]     createUser
2       UserResource    [R]     getUser UserCollectionResource  [R]     getUsers
3       UserResource    [U]     updateUser      UserCollectionResource  [U]     N/A
4       UserResource    [D]     deleteUser      UserCollectionResource  [D]     N/A
5       UserInfoResource        [C]     N/A     UserInfoCollectionResource      [C]     N/A
6       UserInfoResource        [R]     getUserInfo     UserInfoCollectionResource      [R]     getUserInfo
7       UserInfoResource        [U]     setUserInfo     UserInfoCollectionResource      [U]     setUserInfo
8       UserInfoResource        [D]     deleteUserInfo  UserInfoCollectionResource      [D]     N/A
9       UserPictureResource     [C]     N/A     N/A
10      UserPictureResource     [R]     getUserPicture  N/A
11      UserPictureResource     [U]     updateUserPicture       N/A
12      UserPictureResource     [D]     N/A     N/A


# 法則性の無さが気持ち悪い..
# DBのレコードのCreateができるのは UserResource の Collection の方のみ
# Deleteができるのはシングル操作の制御クラスのみ (UserResource )


■ 詳細:
Activiti v6.0.0 の資材から@RequestMappingで逆引きした一覧
# エクセルに張り付けて見て。

project package Class   L       Method  RequestBody     Return  HTTP Method     Path
activiti-rest   org.activiti.rest.service.api.identity  UserCollectionResource.java (2 matches) 87      getUsers                DataResponse    GET     /identity/users
activiti-rest   org.activiti.rest.service.api.identity  UserCollectionResource.java (2 matches) 127     createUser      UserRequest             POST    /identity/users
activiti-rest   org.activiti.rest.service.api.identity  UserInfoCollectionResource.java (2 matches)     59      getUserInfo             List  GET     /identity/users/{userId}/info
activiti-rest   org.activiti.rest.service.api.identity  UserInfoCollectionResource.java (2 matches)     73      setUserInfo     UserInfoRequest         POST    /identity/users/{userId}/info
activiti-rest   org.activiti.rest.service.api.identity  UserInfoResource.java (3 matches)       57      getUserInfo             UserInfoResponse        GET     /identity/users/{userId}/info/{key}
activiti-rest   org.activiti.rest.service.api.identity  UserInfoResource.java (3 matches)       75      setUserInfo     UserInfoRequest UserInfoResponse        PUT     /identity/users/{userId}/info/{key}
activiti-rest   org.activiti.rest.service.api.identity  UserInfoResource.java (3 matches)       99      deleteUserInfo          void    DELETE   /identity/users/{userId}/info/{key}
activiti-rest   org.activiti.rest.service.api.identity  UserPictureResource.java (2 matches)    59      getUserPicture          ResponseEntity  GET      /identity/users/{userId}/picture
activiti-rest   org.activiti.rest.service.api.identity  UserPictureResource.java (2 matches)    91      updateUserPicture               void    PUT      /identity/users/{userId}/picture
activiti-rest   org.activiti.rest.service.api.identity  UserResource.java (3 matches)   46      getUser         UserResponse    GET     /identity/users/{userId}
activiti-rest   org.activiti.rest.service.api.identity  UserResource.java (3 matches)   61      updateUser      UserRequest     UserResponse    PUT     /identity/users/{userId}
activiti-rest   org.activiti.rest.service.api.identity  UserResource.java (3 matches)   87      deleteUser              void    DELETE   /identity/users/{userId}


■ プロジェクト activiti-rest の解析
/activiti-rest/src/main/webapp/WEB-INF/web.xml
listener-class: org.activiti.rest.common.servlet.ActivitiServletContextListener
このListener内でデフォルトのProcessEngineを使うとしている。
processEngine = ProcessEngines.getDefaultProcessEngine()
逆に独自のProcessEngineを使用したい場合は、ココをカスタマイズすれば良い筈
そのカスタマイズは、activiti.cfg.xml ないし activiti-context.xml で設定されるものと思われる。
cf.
void org.activiti.engine.ProcessEngines.init() - ProcessEngines
Initializes all process engines that can be found on the classpath for resources activiti.cfg.xml (plain Activiti style configuration) and for resources activiti-context.xml (Spring style configuration).


■ おまけ①
「user」をRequestMappingに持つ制御クラスは、
プロジェクト activiti-admin のパッケージ com.activiti.web.rest.client
プロジェクト activiti-app-rest のパッケージ org.activiti.app.rest.idm
にもある。
前者はユーザ認証などを担うクライアントアプリだろう
後者は「恐らく」IDM(アイデンティティ管理)を実装したところだろう
cf.
IDM = Identity management or Identity and Access Management

■ おまけ②
Activiti を DL して展開すると溢れんばかりのプロジェクトがお目見えするが、
その中で重要なのは以下の輩たちのみ (全部で 8 コ)
activiti-bpmn-model
activiti-process-validation
activiti-image-generator
activiti-bpmn-layout
activiti-bpmn-converter
activiti-json-converter
activiti-engine
activiti-spring
他は全部サンプル!


ref.
内部統制で注目される機能は「ワークフロー」と「監査」 (1/3)
http://www.itmedia.co.jp/enterprise/articles/0606/02/news002.html
カタログでは決して分からないID管理製品の選択基準 (1/3)
http://www.itmedia.co.jp/enterprise/articles/0606/06/news004.html
Activiti & Activiti Cloud
https://community.alfresco.com/community/bpm/blog/2017/08/22/activiti-activiti-cloud
"We are not providing any homegrown SSO/IDM mechanism as most of the BPM engines out there do. Instead, we are delegating that responsibility to a component that has been designed for providing that integration layer with SSO and IDM specific implementations."

tag : Activiti BPM BPMN v6.0.0 UserResource UserCollectionResource UserInfoResource UserInfoCollectionResource UserPictureResource IDM

2017-11-08 01:05 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] spring-boot-starter がコンパイルエラーになる

tag.
mvn Maven clean install NoClassDefFoundError spring-boot-maven-plugin pom UnsatisfiedDependencyException standardJacksonObjectMapperBuilderCustomizer

Failure to transfer org.springframework.boot:spring-boot-maven-plugin:pom:1.5.8.RELEASE from https://repo.maven.apache.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced. Original error: Could not transfer artifact org.springframework.boot:spring-boot-maven-plugin:pom:1.5.8.RELEASE from/to central (https://repo.maven.apache.org/maven2): Connection reset

@command prompt
cd {directory of the target project}
mvn clean install

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'standardJacksonObjectMapperBuilderCustomizer' defined in class path resource [org/springframework/boot/autoconfigure/jackson/JacksonAutoConfiguration$Jackson2ObjectMapperBuilderCustomizerConfiguration.class]: Unsatisfied dependency expressed through method 'standardJacksonObjectMapperBuilderCustomizer' parameter 1; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'spring.jackson-org.springframework.boot.autoconfigure.jackson.JacksonProperties': Failed to introspect bean class [org.springframework.boot.autoconfigure.jackson.JacksonProperties] for lookup method metadata: could not find class that it depends on; nested exception is java.lang.NoClassDefFoundError: com/fasterxml/jackson/annotation/JsonInclude$Include
        at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]

なんかUTでコケてる気配もある。

@STS
Preferences > General > Network Connections:
Active Provider: Manual
HTTPとHTTPSにproxy通過用のUser/Passwordを設定
Apply and Close
@STS
Package Explorer > {Target Project} > Context Menu > Update Project
でエラー消えた

tag : mvn Maven clean install NoClassDefFoundError spring-boot-maven-plugin pom UnsatisfiedDependencyException standardJacksonObjectMapperBuilderCustomizer

2017-11-08 01:03 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] Activiti (v6.0.0) で使用されているテーブル一覧と主要操作でのCRUD

tag. BPMN BPM Activiti CRUD

CRUD - ユーザ管理系

新規ユーザ作成
C ACT_ID_USER

新規グループ作成
C ACT_ID_GROUP

グループへのユーザ割当
C ACT_ID_MEMBERSHIP

ユーザログイン
C act_idm_persistent_token

CRUD - プロセス定義系

新規モデルの作成
C act_de_model

新規アプリの作成
C act_de_model

アプリへのモデルの紐づけ
C act_de_model_relation
U act_de_model

アプリのパブリッシュ
C ACT_GE_BYTEARRAY
C ACT_RE_DEPLOYMENT
C ACT_RE_PROCDEF
C act_de_model_history
U act_de_model

プロセスの開始
C ACT_RU_EXECUTION
C ACT_RU_TASK
C ACT_RU_IDENTITYLINK
C ACT_RU_VARIABLE
C ACT_HI_PROCINST
C ACT_HI_ACTINST
C ACT_HI_TASKINST
C ACT_HI_VARINST
C ACT_HI_IDENTITYLINK

タスクの終了
U ACT_RU_EXECUTION
D ACT_RU_TASK
C ACT_RU_TASK
U ACT_HI_ACTINST
C ACT_HI_ACTINST
U ACT_HI_TASKINST
C ACT_HI_TASKINST

開始済みプロセスタスクへの担当割当(CLAIM)
U ACT_RU_TASK
U ACT_HI_ACTINST
U ACT_HI_TASKINST

開始済みプロセスタスクへの担当割当(CLAIM)
C ACT_RU_IDENTITYLINK
C ACT_HI_COMMENT
C ACT_HI_IDENTITYLINK

プロセスの完了
C ACT_RU_EXECUTION
C ACT_RU_TASK
C ACT_RU_IDENTITYLINK
C ACT_RU_VARIABLE
U ACT_HI_PROCINST
U ACT_HI_ACTINST
C ACT_HI_ACTINST
U ACT_HI_TASKINST
C ACT_HI_COMMENT
C ACT_HI_IDENTITYLINK


■ テーブル一覧
# 大文字記載はactiviti.*.create.*.sqlに定義のあるもの
# 小文字記載はactiviti.*.create.*.sqlに定義が無いもの

act_de_databasechangelog
act_de_databasechangeloglock
act_de_model
act_de_model_history
act_de_model_relation

act_dmn_databasechangelog
act_dmn_databasechangeloglock
act_dmn_decision_table
act_dmn_deployment
act_dmn_deployment_resource

ACT_EVT_LOG

act_fo_databasechangelog
act_fo_databasechangeloglock
act_fo_form_definition
act_fo_form_deployment
act_fo_form_resource
act_fo_submitted_form

ACT_GE_BYTEARRAY
ACT_GE_PROPERTY

ACT_HI_ACTINST
ACT_HI_ATTACHMENT
ACT_HI_COMMENT
ACT_HI_DETAIL
ACT_HI_IDENTITYLINK
ACT_HI_PROCINST
ACT_HI_TASKINST
ACT_HI_VARINST

ACT_ID_GROUP
ACT_ID_INFO
ACT_ID_MEMBERSHIP
ACT_ID_USER

act_idm_persistent_token

ACT_PROCDEF_INFO

ACT_RE_DEPLOYMENT
ACT_RE_MODEL
ACT_RE_PROCDEF

ACT_RU_DEADLETTER_JOB
ACT_RU_EVENT_SUBSCR
ACT_RU_EXECUTION
ACT_RU_IDENTITYLINK
ACT_RU_JOB
ACT_RU_SUSPENDED_JOB
ACT_RU_TASK
ACT_RU_TIMER_JOB
ACT_RU_VARIABLE

act_wo_comments
act_wo_related_content

hibernate_sequences

tag : BPMN BPM Activiti CRUD

2017-10-19 20:38 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] Activiti の WEBアプリの接続先DBをデフォルトのH2からPostgreSQLに変える

tag. Activiti BPM REST STS DB PostgreSQL H2 Maven pom

■ /activiti-app/src/main/resources/META-INF/activiti-app/activiti-app.properties
#datasource.driver=org.h2.Driver
#datasource.url=jdbc:h2:mem:activiti;DB_CLOSE_DELAY=-1
#datasource.username=sa
#datasource.password=
#hibernate.dialect=org.hibernate.dialect.H2Dialect

datasource.driver=org.postgresql.Driver
datasource.url=jdbc:postgresql://127.0.0.1:5432/activiti
datasource.username=admin
datasource.password=P@ssword
hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect

■ /activiti-app/pom.xml
    <'!--
    <'dependency>
      <'groupId>com.h2database<'/groupId>
      <'artifactId>h2<'/artifactId>
    <'/dependency>
    <'dependency>
      <'groupId>mysql<'/groupId>
      <'artifactId>mysql-connector-java<'/artifactId>
    <'/dependency>
     -->
    <'dependency>
      <'groupId>org.postgresql<'/groupId>
      <'artifactId>postgresql<'/artifactId>
      <'version>42.1.4<'/version>
      <'scope>runtime<'/scope>
    <'/dependency>

■ /activiti-app
STS (Eclipse) > Package Explorer > activiti-app > Context Menu > Maven > Update Project

tag : Activiti BPM REST STS DB PostgreSQL H2 Maven pom

2017-10-19 20:37 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] PostgreSQLからコマンドでDBのデータをexportする

tag.
DB PostgrSQL export table PSQL pgAdmin

# pgAdmin4 には一括実行的な便利機能なし
# テーブルを1つ選んでコンテキストメニューでexportウィザードを実行せないけん

[1] コマンドプロンプトを実行
[2] PSQLでログインコマンド実行
C:\Users\TestUser> "C:\Program Files\PostgreSQL\9.6\bin\psql.exe" -U admin -d mydatabase
[3] ログインユーザのパスワードを入力
P@ssword
[4] テーブルのexportコマンドを実行 (「C:」は割愛可)
COPY SAMPLE_TABLE TO ' /tmp/postgres_sonapshot/ SAMPLE_TABLE .csv' WITH CSV DELIMITER ',' FORCE QUOTE * NULL AS '' HEADER;

cf. テーブル一覧取得
select relname as TABLE_NAME from pg_stat_user_tables;


ref.
第3章 psqlによるPostgreSQLの操作, Windows+Apache+PHP+PostgreSQLによるWebアプリケーション-入門編-
http://www.yc.tcu.ac.jp/~yamada/doc/pgsql/0301.html
PostgreSQLのCSV出力(Export)方法
https://qiita.com/cyborg__ninja/items/99efcb5b62a4cef2f156
PostgreSQLにてテーブルやカラムの各種情報を取得するSQL (テーブル一覧, カラム一覧, プライマリーキー情報取得, テーブルのコメントを取得, カラムのコメントを取得)
http://devlights.hatenablog.com/entry/20080226/p1

tag : DB PostgrSQL export table PSQL pgAdmin

2017-10-19 20:35 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] ワークフローエンジン Activiti のカスタマイズ方法

tag. BPMN Activiti Spring customize activiti-ctx.cfg.xml context-param

■ 備考

事半ばで放置中
Activiti Explorer が v6でも現役なのかが知りたい。多分ちがう

以下は、軽量なSpringのブランクプロジェクトで出直しするが宜し。

あと User Guide にあった以下の記述も気になる

6.2.2. Using Spring beans from a process
When expressions or scripts use Spring beans, those beans have to be available to the engine when executing the process definition. If you are building your own webapp and you configure your process engine in your context as described in the spring integration section, that is straightforward. But bear in mind that you also should update the Activiti rest webapp with that context if you use it. You can do that by replacing the activiti.cfg.xml in the activiti-rest/lib/activiti-cfg.jar JAR file with an activiti-context.xml file containing your Spring context configuration.

--------------------

Activitiを拡張するも独自のアプリに組み込むもProcessEngineを設定をいじれば良い。

□ 参考
ダウンロード
https://www.activiti.org/download-links
activiti-6.0.0.zip (warファイルのみ版) >> https://github.com/Activiti/Activiti/releases/download/activiti-6.0.0/activiti-6.0.0.zip
Activiti-6.0-release.zip (リポジトリ全部) >> https://github.com/Activiti/Activiti/archive/6.0-release.zip
cf.
https://github.com/Activiti/Activiti/tree/6.0-release

ご本家のサンプル達
https://github.com/Activiti/Activiti/tree/6.0-release/modules/activiti-spring-boot/spring-boot-samples
ご本家のプロジェクト達
https://github.com/activiti
前versionからの変更箇所
https://www.activiti.org/migration.html

■ Activitiの設定ファイルの読み込み
アプリのweb.xmlにて以下のようにActivitiの設定ファイル(activiti-ctx.cfg.xml)を読み込むようcontext-paramを指定する。
もしくは、既存のBean定義ファイルにimportさせる。
# 単純な軽量の実験アプリを作るのなら前者(context-paramでクラスパスを指定する方法)
# そこそこのボリュームのアプリに組み込むのなら後者(既存のBean定義ファイルにimportさせる方法)が良かろう
# web.xmlとかミドル寄りより既存bean定義ファイルなどまだアプリ寄りなとこのが問題切り分けが楽そうだから

context-paramを指定する場合
<'?xml version='1.0' encoding='UTF-8'?>
<'!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

<'web-app>
<'!-- Spring Application Context location -->
<'context-param>
<'param-name>contextConfigLocation<'/param-name>
<'!-- Root ApplicationContext -->
<'param-value>
classpath*:META-INF/spring/applicationContext.xml
classpath*:META-INF/spring/spring-security.xml
classpath*:META-INF/activiti/activiti-ctx.cfg.xml
<'/param-value>
<'/context-param>

Activitiの設定ファイルでProcessEngineの設定を定義する
/activitistudy/src/main/resources/META-INF/activiti/activiti-ctx.cfg.xml

□ 既存のBean定義ファイルにimportさせる場合
/activitistudy/src/main/resources/META-INF/spring/applicationContext.xml
<'import resource="classpath:/META-INF/activiti/activiti-ctx.cfg.xml" />


■ Activitiの設定ファイルの定義例
/activitistudy/src/main/resources/META-INF/spring/applicationContext.xml
サンプルはActivitiのテストコードに格納されているクラス参照
# Eclipse で Activiti 一式を import した後、
# id="processEngineConfiguration" で CTRL+SHIFT+L すれば良い

<'beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans.xsd
    ">

  <'!-- 用途に合ったProcessEngineConfiguration実装クラスを指定すること -->
  <'bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
    <'!-- デフォルトの規定クラス ProcessEngineConfigurationImpl を使用する場合は
h2, hsql, mysql, oracle, postgres, mssql, db2 から選択する
参照: org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl.databaseTypeMappings
     -->
    <'property name="databaseType" value="postgres"/>
    <'property name="dataSource" ref="dataSource"/><'!-- activitistudy-env.xmlに定義済みのbeanをDI -->
    <'property name="transactionManager" ref="transactionManager"/><'!-- activitistudy-env.xmlに定義済みのbeanをDI -->

    <'property name="databaseSchemaUpdate" value="true"/>
    <'property name="deploymentResources" value="classpath*:/process/*.bpmn20.xml"/>
  <'/bean>

  <'bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
    <'property name="processEngineConfiguration" ref="processEngineConfiguration"/>
  <'/bean>

<'/beans>


■ 依存関係の追記
/activitistudy/pom.xml
    <'dependency>
      <'groupId>org.activiti<'/groupId>
      <'artifactId>activiti-engine<'/artifactId>
      <'version>6.0.0<'/version>
    <'/dependency>
    <'dependency>
      <'groupId>org.activiti<'/groupId>
      <'artifactId>activiti-spring<'/artifactId>
      <'version>6.0.0<'/version>
    <'/dependency>

project > context menu > Maven > Update Project

■ ProcessEngineConfiguration の実装クラス
どれ使うべきかよく分からない時は取り合えずStandaloneProcessEngineConfigurationを使っとけ

org.activiti.engine.ProcessEngineConfiguration
 ⎿ ProcessEngineConfigurationImpl - org.activiti.engine.impl.cfg
    ├ JtaProcessEngineConfiguration
    ├ MultiSchemaMultiTenantProcessEngineConfiguration - org.activiti.impl.cfg.multitenant
    ├ SpringProcessEngineConfiguration
    ⎿ StandaloneProcessEngineConfiguration
       ⎿ StandaloneInMemProcessEngineConfiguration

■ ProcessEngine のビルド方法

方法① デフォルト構成ファイルからProcessEngineを生成する
ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResourceDefault().buildProcessEngine();
独自設定する場合は、buildProcessEngineを呼ぶ前に
ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResourceDefault()
  .setMailServerHost("gmail.com").setJdbcUsername("mickey").setJdbcPassword("mouse")
  .buildProcessEngine();

方法② 独自の構成ファイルからProcessEngineを生成する
ProcessEngine processEngine = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration().buildProcessEngine();
# Standaloneで生成される=トランザクションはActivitiがサービス毎に管理する

方法③ 試験時に有用な方法
ProcessEngine processEngine = ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration().buildProcessEngine();

■ Activiti の資材本体と Activiti 資材同士の依存性 - based on Master branch, as of 20171017
https://github.com/Activiti/Activiti

- activiti-bpmn-converter >> depends on -- activiti-bpmn-model, activiti-process-validation, activiti-bpmn-layout -- parent: activiti-root
- activiti-bpmn-layout >> depends on -- activiti-bpmn-model -- parent: activiti-root
- activiti-bpmn-model >> depends on -- nothing -- parent: activiti-root
- activiti-engine >> depends on -- activiti-bpmn-converter, activiti-bpmn-model, activiti-process-validation -- parent: activiti-root
- activiti-image-generator >> depends on -- activiti-bpmn-model -- parent: activiti-root
- activiti-json-converter >> depends on -- activiti-bpmn-model, activiti-bpmn-converter -- parent: activiti-root
activiti-process-validation >> depends on -- activiti-bpmn-model -- parent: activiti-root
activiti-spring >> depends on -- activiti-engine -- parent: activiti-root

activiti-root
https://mvnrepository.com/artifact/org.activiti/activiti-root/6.0.0
# 相互参照してる?
activiti-secure-tasks 6.0.0
activiti-engine (BPM Engine) 6.0.0
activiti-spring 6.0.0
activiti-bpmn-model 6.0.0
activiti-bpmn-converter 6.0.0
activiti-json-converter 6.0.0
activiti-explorer 5.22.0
activiti-simple-workflow 5.22.0
activiti-common-rest 6.0.0
activiti-rest 6.0.0
activiti-dmn-api 6.0.0
activiti-dmn-engine 6.0.0
activiti-dmn-model 6.0.0
activiti-dmn-xml-converter 6.0.0
activiti-dmn-json-converter 6.0.0
activiti-dmn-rest 6.0.0
activiti-dmn-engine-configurator 6.0.0
activiti-form-model 6.0.0
activiti-form-api 6.0.0
activiti-form-json-converter 6.0.0
activiti-form-engine 6.0.0
activiti-form-engine-configurator 6.0.0
activiti-camel 6.0.0
activiti-mule 6.0.0
activiti-crystalball 6.0.0
activiti-webapp-rest2 (Web App) 6.0.0
activiti-cxf 6.0.0
activiti-bpmn-layout 6.0.0
activiti-process-validation 6.0.0
activiti-image-generator 6.0.0
activiti5-engine 6.0.0
activiti5-spring 6.0.0
activiti5-compatibility 6.0.0
activiti5-spring-compatibility 6.0.0
activiti-jmx 6.0.0


■ Referenced file contains errors
依存するライブラリのバージョンに矛盾があるとBean定義にエラーが出る。
Description Resource Path Location Type
Referenced file contains errors (project-aware://activitistudy/org/springframework/beans/factory/xml/spring-beans-4.3.xsd). For more information, right click on the message in the Problems View and select "Show Details..." activitistudy-infra.xml /activitistudy/src/main/resources/META-INF/spring line 1 XML Problem
Referenced file contains errors (project-aware://activitistudy/org/springframework/beans/factory/xml/spring-tool-4.3.xsd). For more information, right click on the message in the Problems View and select "Show Details..." activitistudy-infra.xml /activitistudy/src/main/resources/META-INF/spring line 1 XML Problem
Referenced file contains errors (project-aware://activitistudy/org/springframework/context/config/spring-context-4.3.xsd). For more information, right click on the message in the Problems View and select "Show Details..." activitistudy-infra.xml /activitistudy/src/main/resources/META-INF/spring line 1 XML Problem
自分のアプリpomにて使用するバージョンを上書き定義して、プロジェクト>Maven>Update Project>プロジェクトクリーンすれば良いが、
スパゲッティ過ぎて断念。。。
<'dependencies>
<'dependency>
<'groupId>org.springframework<'/groupId>
<'artifactId>spring-beans<'/artifactId>
<'version>${org.springframework.version}<'/version>
<'/dependency>
<'/dependencies>
  <'properties>
    <'!-- == Spring Version == --><'!-- althoug activiti-webapp-rest2 is using 4.2.5.RELEASE. -->
    <'org.springframework.version>4.3.5.RELEASE<'/org.springframework.version>
  <'/properties>


tag : BPMN Activiti Spring customize activiti-ctx.cfg.xml context-param

2017-10-18 08:09 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] ワークフローエンジンのActivitiという奴

tag. BPMN Activiti API Engine Query

Activitiのcomponent群-3つ
◎ モデリング-Activiti Modeler, Activiti Designer*, Activiti Kickstart
◎ ランタイム - Activiti Engine
◎ 管理 - Activiti Explorer, Activiti REST

* Eclipse > Install New Software
Name: Activiti BPMN 2.0 designer (任意)
Location: https://activiti.org/designer/update/
# location は、http://activiti.org/designer/update/ もトライする価値あり
# ダメな場合はzipをDLして解凍し、local locationを指定すれば良い筈だが、
# zip のDLが見つからない
ref. http://docs.alfresco.com/5.2/tasks/wf-install-activiti-designer.html

Activiti Engineの利用方法 - 2つ
◎ Activiti Engineをライブラリとして業務アプリに組み込む方法。
◎ 業務アプリからRESTでActiviti Engineアプリのサービスを呼ぶ方法

------------------------------

Activitiが提供するAPIは二つ-エンジンAPIとクエリAPI
まずは、Engine API (Process Engine API)から。

■ Process Engine API
始点となるのがProcessEngine - 複数の方法から作成される
ProcessEngineから様々なServiceを取得できる
サービスは、workflowやBPM メソッドを保有する
ProcessEngineとServiceオブジェクトはスレッドセーフで、いずれのサービスもステートレス

activiti.cfg.xml --> ProcessEnginConfiguration --> ProcesEngine
--> RepositoryService, TaskService, IndetityService, FormService, RuntimeService, ManagementService, HistoryService

e.g.
// すべてのactiviti.cfg.xml と activiti-context.xmlを読み込んでインスタンスを初期化生成する
// activiti.cfg.xml は、ProcessEngineConfiguration
// .createProcessEngineConfigurationFromInputStream(inputStream)
// .buildProcessEngine() で読まれ、activiti-context.xml は、Spring が読み込む
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();

■ RepositoryService
static informationな位置づけ。(変更頻度は高くない)

■ RuntimeService
RepositoryServiceと対照的で、staticでない
プロセス定義に準じて新規Processインスタンスを開始させる。
各プロセスの変数を格納しているのがこのRuntimeService

■ TaskService
BPMのタスク関連の処理を担うもの

■ IdentityServce
グループとユーザを管理するサービス
留意:
Activitiは、そんなにvalidation掛けない。-LDAPやAcitive Directoryとの連携も想定している為

■ FormService
任意のサービス
start form と task form が概念のもの
start formは、userがprocessを開始させる前に呼ばれるもので、
task formは、userが任意のformをcompleteさせたい時に呼ばれる

■ HistoryService
履歴情報を見るためのもの

■ ManagementService
Activitiを使ったアプリのカスタマイズで必要ないもの
DBやTableのメタ情報を管理する

■ DynamicBpmnService
デプロイ無しにプロセス定義を部分的に変更できる

Activii APIでの例外は、非検査例外のorg.activiti.engine.ActivitiExceptionが投げられる


■ なんとなく流れ
プロセスを定義して
プロセスをデプロイして
プロセスインスタンスを開始して
タスクをコンプリートしてく

----------

プロセス定義ファイルの作成
<'?xml version="1.0" encoding="UTF-8" ?>
<'definitions id="definitions"
       targetNamespace="http://activiti.org/bpmn20"
       xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:activiti="http://activiti.org/bpmn">

 <'process id="vacationRequest" name="Vacation request">
  ...

そのプロセスをデプロイしてActiviti Engine に認識させる
デプロイによって当該プロセスの情報がDBに登録される
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
repositoryService.createDeployment()
 .addClasspathResource("org/activiti/test/VacationRequest.bpmn20.xml")
 .deploy();
Log.info("Number of process definitions: " + repositoryService.createProcessDefinitionQuery().count())

プロセスインスタンスを開始させる
デプロイできたらプロセスインスタンスを開始できる
各プロセスインスタンスの状態はRuntimeServiceで確認できる
各プロセスインスタンス特有の情報はプロセス変数で保持する。
それらを基にインスタンスは生成させる

Map<'String, Object> variables = new HashMap<'String, Object>();
variables.put("employeeName", "Kermit");
variables.put("numberOfDays", new Integer(4));
variables.put("vacationMotivation", "I'm really tired!");

RuntimeService runtimeService = processEngine.getRuntimeService();
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("vacationRequest", variables);

// Verify that we started a new process instance
Log.info("Number of process instances: " + runtimeService.createProcessInstanceQuery().count());

インスタンスを開始したら次はユーザタスクの実行
各ユーザ事にタスクを保持する箱がある
// Fetch all tasks for the management group
TaskService taskService = processEngine.getTaskService();
List<'Task> tasks = taskService.createTaskQuery().taskCandidateGroup("management").list();
for (Task task : tasks) {
 Log.info("Task available: " + task.getName());
}

各タスクを順次にcompleteすることでプロセスが進む
Task task = tasks.get(0);
Map<'String, Object> taskVariables = new HashMap<'String, Object>();
taskVariables.put("vacationApproved", "false");
taskVariables.put("managerMotivation", "We have a tight deadline!");
taskService.complete(task.getId(), taskVariables);

プロセスをサスペンドさせることも可能
サスペンドさせるとreactivateするまで新規プロセスインスタンスの生成はできなくなる
repositoryService.suspendProcessDefinitionByKey("vacationRequest");
try {
 runtimeService.startProcessInstanceByKey("vacationRequest");
} catch (ActivitiException e) {
 e.printStackTrace();
}

tag : BPMN Activiti API Engine QueryModeler REST

2017-10-18 08:07 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] TomcatでJTAでサーバ起動エラー

tag.
Tomcat LifecycleException TomcatInstrumentableClassLoader Spring ClassNotFoundException JTA

■ 事象
Tomcat起動でエラーになる
10 13, 2017 5:46:13 午後 org.apache.catalina.loader.WebappLoader startInternal
重大: LifecycleException
java.lang.ClassNotFoundException: org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)

■ 対処
http://central.maven.org/maven2/org/springframework/spring-instrument-tomcat/3.0.4.RELEASE/spring-instrument-tomcat-3.0.4.RELEASE.jar
から、
spring-instrument-tomcat-3.0.4.RELEASE.jar
を取得して、
C:\Program Files\Apache Software Foundation\Tomcat 8.5\lib
に格納する

tag : Tomcat LifecycleException TomcatInstrumentableClassLoader Spring ClassNotFoundException JTA

2017-10-14 10:51 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] Tomcatのserver.xmlにListener追加した途端にClassNotFoundException

■ 事象
C:\{workspace}\Servers\Tomcat v8.5 Server at localhost-config\server.xml
に以下を足した途端にClassNotFoundExceptionTomcatが起動できなくなる


■ 対処
以下の jar を Tomcat の lib に追加した >> 解決
対象ライブラリ
persistence-api-1.0.2.jar
jta-1.1.jar
取得先
http://central.maven.org/maven2/javax/transaction/jta/1.1/jta-1.1.jar http://central.maven.org/maven2/javax/persistence/persistence-api/1.0.2/persistence-api-1.0.2.jar
格納先
C:\Program Files\Apache Software Foundation\Tomcat 8.5\lib

□ ログ
重大: The required Server component failed to start so Tomcat is unable to start.
org.apache.catalina.LifecycleException: Failed to start component [StandardServer[8005]]
  at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167)
Caused by: java.lang.NoClassDefFoundError: javax/transaction/TransactionManager
  at java.lang.ClassLoader.defineClass1(Native Method)
Caused by: java.lang.ClassNotFoundException: javax.transaction.TransactionManager
  at java.net.URLClassLoader.findClass(Unknown Source)

■ 参考
Webapps (version 3.7.4) cannot be deployed after installation due to NoSuchMethodError, Zoltán Farkas - 2016-02-12
https://sourceforge.net/p/guse/discussion/1672628/thread/4aa465ec/

tag : Tomcat server Listener ClassNotFoundException JTA atomikos

2017-10-14 10:49 : 開発 : コメント : 0 : トラックバック : 0 :

[開発] TomcatとAtomikosでJTA

tag.
Tomcat JTA Atomikos TransactionsEssentials ExtremeTransactions jar server context DB lookup UserTransaction UserTransactionManager ConnectionFactory

■ そもそも
ATOMIKOSには大きく2製品ある- TransactionsEssentialsExtremeTransactions
TransactionsEssentials >> 無償
ExtremeTransactions >> 有償

TransactionsEssentials
https://www.atomikos.com/Main/TransactionsEssentials
ランセンスは、Apache license, second version
本製品を使用したアプリソース公開義務なし
https://www.atomikos.com/Main/FrequentlyAskedQuestions#A_1.2._Is_the_40open_source_41_license_viral_63
Download Here
https://github.com/atomikos/transactions-essentials/archive/master.zip

ExtremeTransactions
https://www.atomikos.com/Main/ExtremeTransactions
ミッションクリティカルをサポートし、クラウド環境やビルドインのサーバにも対応する。性能も最適化されるそう
1500 ~ 14500 €/year

■ 方法 - まだ成功していない

1
AtomikosjarTomcatに移植
transactions.jar
transactions-api.jar
transactions-jta.jar
transactions-jdbc.jar
atomikos-util.jar
jta.jar - 発見ならず
atomikos-integration-extension-3.7.1-20120529.jar
atomikos-integration-extension-3.7.2.jar
を、TOMCAT_HOME/lib に配置する。
このjarは、以下を包含する
- 'AtomikosLifecycleListener.java'
- 'EnhancedTomcatAtomikosBeanFactory.java'
- 'pom.xml'
- 'patch-README.txt'  
# atomikos-integration-extension-{version}-patch.zipの方はソースコードなので一旦放置

2
server.xmlを編集する
リスナをTomcatに足す
TOMCAT_HOME/conf/server.xmlの最後に以下の定義を追記する
# STS/Eclipse上でTomcat(build-in Tomcat)動かす場合は、
# C:\{workspace}\Servers\Tomcat v8.5 Server at localhost-config\server.xml
<'Listener className="com.atomikos.tomcat.AtomikosLifecycleListener" />

3
TOMCAT_HOME/conf/context.xmlを編集する
# STS/Eclipse上でTomcat(build-in Tomcat)動かす場合は、
# C:\{workspace}\Servers\Tomcat v8.5 Server at localhost-config\context.xml

まず、以下の一文が冒頭にあること
<'WatchedResource>WEB-INF/web.xml<'/WatchedResource>
その後に、UserTransactionFactoryとUserTransactionManagerの定義を追記する
<'!-- Atomikos Support for the Tomcat server - register Atomikos as java:comp/UserTransaction -->
<'Transaction factory="com.atomikos.icatch.jta.UserTransactionFactory" />
<'!-- Also register Atomikos TransactionManager as java:comp/env/TransactionManager -->
<'Resource name="TransactionManager"
     auth="Container"
     type="com.atomikos.icatch.jta.UserTransactionManager"
     factory="org.apache.naming.factory.BeanFactory" />

クラスロードも定義し-要否不明..
<'!-- Spring LoadTimeWeaver Support for the Tomcat server. -->
<'Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"
    useSystemClassLoaderAsParent="false"/>

DBなりJMSなりリソースを定義
<'Resource name="jdbc/MyDb"
    auth="Container"
    type="com.atomikos.jdbc.AtomikosDataSourceBean"
    factory="com.atomikos.tomcat.EnhancedTomcatAtomikosBeanFactory"
    uniqueResourceName="MyDb_Resource"
    maxPoolSize="8"
    xaDataSourceClassName="org.apache.derby.jdbc.ClientXADataSource"
    xaProperties.databaseName="MyDb"
    xaProperties.connectionAttributes="serverName=localhost;portNumber=1527;user=USER;password=PASSWORD;create=true"/>

<'Resource name="jms/ConnectionFactory"
    auth="Container"
    type="com.atomikos.jms.AtomikosConnectionFactoryBean"
    factory="com.atomikos.tomcat.EnhancedTomcatAtomikosBeanFactory"
    uniqueResourceName="ConnectionFactory_Resource"
    xaConnectionFactoryClassName="org.apache.activemq.ActiveMQXAConnectionFactory"
    xaProperties.brokerURL="tcp://localhost:61616?daemon=true"/>


yet- If you want to use Atomikos, the XA-datasource must be configured just like you configure any other JTA/XA connection. There is a forum entry describing an example.
http://fogbugz.atomikos.com/default.asp?community.6.2158.4
yet- There is an example you can download to understand the Atomikos-Tomcat configuration.
https://www.atomikos.com/Documentation/Tomcat7Integration35#Example_application
yet- HOWTO: make distributed transactions work in Tomcat, 06 Dec 2016
https://www.atomikos.com/Blog/HOWTOMakeDistributedTransactionsWorkInTomcat
yet- Spring JTA multiple resource transactions in Tomcat with Atomikos example, 2015年03月18日
http://blog.csdn.net/cnhome/article/details/44429917
yet- Correctly setting up JTA Transaction Manager in Tomcat Server with Atomikos, Apr 12 '13
https://stackoverflow.com/questions/15637921/correctly-setting-up-jta-transaction-manager-in-tomcat-server-with-atomikos
8. トランザクション管理 (Ver 1.2.7)
http://www.andore.com/money/trans/spring_ref_p9_ja.html
Spring JTA multiple resource transactions in Tomcat with Atomikos example
http://www.byteslounge.com/tutorials/spring-jta-multiple-resource-transactions-in-tomcat-with-atomikos-example


ref.
Update: Tomcat 7.0.27 Integration with Atomikos 3.7.1
https://www.atomikos.com/Documentation/Tomcat7Integration35
Atomikos in Tomcat 8, how to configurate JDBC resource with XA in the server.xml to as400?, Sep 7, 2017
https://stackoverflow.com/questions/45922254/atomikos-in-tomcat-8-how-to-configurate-jdbc-resource-with-xa-in-the-server-xml

tag : Tomcat JTA Atomikos TransactionsEssentials ExtremeTransactions jar server context DB lookup

2017-10-14 10:48 : 開発 : コメント : 0 : トラックバック : 0 :
ホーム  次のページ »

search

ad



counter


tag cloud

category cloud